Skip to content

[RISCV] Added the MIPS prefetch extensions for MIPS RV64 P8700. #145647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions clang/test/Driver/riscv-cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>(); }
Expand Down Expand Up @@ -1523,6 +1524,9 @@ 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 offset must be in the range");
case Match_InvalidBareSImm9Lsb0:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,9 @@ 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"},
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,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)

Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2925,6 +2925,33 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
return true;
}

/// Similar to SelectAddrRegImm, except that the offset restricted for
/// unsinged 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;
}
}

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,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {

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,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,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);
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_UIMM9_LSB000:
Ok = isShiftedUInt<6, 3>(Imm);
break;
case RISCVOp::OPERAND_UIMM9:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CASE_OPERAND_UIMM(9) like the other unsigned immediates earlier in this switch

Ok = isUInt<9>(Imm);
break;
case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
break;
Expand Down
38 changes: 38 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -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;
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 MIPS_PREFETCH : Mips_prefetch_ri<(outs), (ins GPR:$rs1, uimm9:$imm9, uimm5:$hint),
"mips.pref", "$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)),
(MIPS_PREFETCH GPR:$rs1, uimm9:$imm9, 9)>;
// Prefetch Data Read.
def : Pat<(prefetch (AddrRegImm9 (XLenVT GPR:$rs1), uimm9:$imm9),
(i32 0), timm, (i32 1)),
(MIPS_PREFETCH GPR:$rs1, uimm9:$imm9, 8)>;
}

let Predicates = [HasVendorXMIPSCMov], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
DecoderNamespace = "Xmipscmov" in {
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<[]>;
Expand All @@ -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)>;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/RISCVProcessors.td
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def MIPS_P8700 : RISCVProcessorModel<"mips-p8700",
FeatureStdExtZifencei,
FeatureStdExtZicsr,
FeatureVendorXMIPSCMov,
FeatureVendorXMIPSLSP],
FeatureVendorXMIPSLSP,
FeatureVendorXMIPSCBOP],
[TuneMIPSP8700]>;

def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32",
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/RISCV/features-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,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).
Expand Down
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/RISCV/xmips-cbop.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=riscv32 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though this is a small test, I would still recommend to use UTC (utils/update_llc_test_checks.py) to generate the FileCheck CHECKS

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure ..Will use UTC

; RUN: | FileCheck %s -check-prefix=RV32XMIPSPREFETCH
; RUN: llc -mtriple=riscv64 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64XMIPSPREFETCH

define void @prefetch_read(ptr noundef %ptr) nounwind {
; RV32XMIPSPREFETCH-LABEL: prefetch_read:
; RV32XMIPSPREFETCH: # %bb.0: # %entry
; RV32XMIPSPREFETCH-NEXT: mips.pref 8, 1(a0)
; RV32XMIPSPREFETCH-NEXT: ret
;
; RV64XMIPSPREFETCH-LABEL: prefetch_read:
; RV64XMIPSPREFETCH: # %bb.0: # %entry
; RV64XMIPSPREFETCH-NEXT: mips.pref 8, 1(a0)
; RV64XMIPSPREFETCH-NEXT: ret
entry:
%arrayidx = getelementptr inbounds nuw i8, ptr %ptr, i64 1
tail call void @llvm.prefetch.p0(ptr nonnull %arrayidx, i32 0, i32 0, i32 1)
ret void
}

define void @prefetch_write(ptr noundef %ptr) nounwind {
; RV32XMIPSPREFETCH-LABEL: prefetch_write:
; RV32XMIPSPREFETCH: # %bb.0:
; RV32XMIPSPREFETCH-NEXT: addi a0, a0, 512
; RV32XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0)
; RV32XMIPSPREFETCH-NEXT: ret
;
; RV64XMIPSPREFETCH-LABEL: prefetch_write:
; RV64XMIPSPREFETCH: # %bb.0:
; RV64XMIPSPREFETCH-NEXT: addi a0, a0, 512
; RV64XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0)
; RV64XMIPSPREFETCH-NEXT: ret
%arrayidx = getelementptr inbounds nuw i8, ptr %ptr, i64 512
tail call void @llvm.prefetch.p0(ptr nonnull %arrayidx, i32 1, i32 0, i32 1)
ret void
}

11 changes: 10 additions & 1 deletion llvm/test/MC/RISCV/xmips-invalid.s
Original file line number Diff line number Diff line change
@@ -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,+Xmipscbop < %s 2>&1 | FileCheck %s

mips.pref 8, 512(a0)
# CHECK: error: immediate offset must be in the range [0, 511]

mips.pref 8
# CHECK: error: too few operands for instruction

mips.pref 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
Expand Down
18 changes: 15 additions & 3 deletions llvm/test/MC/RISCV/xmips-valid.s
Original file line number Diff line number Diff line change
@@ -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.pref 8, 511(a0)
# CHECK-ENC: encoding: [0x0b,0x04,0xf5,0x1f]
mips.pref 8, 511(a0)

# CHECK-DIS: mips.pref 0x8, 0x1ff(a0)

# CHECK-INST: mips.pref 9, 0(a0)
# CHECK-ENC: encoding: [0x8b,0x04,0x05,0x00]
mips.pref 9, 0(a0)

# CHECK-DIS: mips.pref 0x9, 0x0(a0)

# CHECK-INST: mips.ccmov s0, s1, s2, s3
# CHECK-ENC: encoding: [0x0b,0x34,0x99,0x9e]
mips.ccmov s0, s1, s2, s3
Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,7 @@ R"(All available -march extensions for RISC-V
xcvmac 1.0
xcvmem 1.0
xcvsimd 1.0
xmipscbop 1.0
xmipscmov 1.0
xmipslsp 1.0
xsfcease 1.0
Expand Down