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.m...@gmail.com> Date: Wed, 25 Jun 2025 06:58:37 +0000 Subject: [PATCH 1/4] 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 ff11413f43a78eb0c30009680703ae54918b5069 Mon Sep 17 00:00:00 2001 From: Umesh Kalappa <ukalappa.m...@gmail.com> Date: Wed, 25 Jun 2025 14:07:38 +0000 Subject: [PATCH 2/4] Updated mcpu for mips-p8700 and related testcase for xmipscbop extension. --- clang/test/Driver/riscv-cpus.c | 3 +++ llvm/lib/Target/RISCV/RISCVProcessors.td | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c index 3736e76ed06dd..d32d1c1a8183f 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" diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td index 57b415dc713ac..03214fe8239ce 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", >From 7962538724d5047431b671cb80d271fe45eba8f6 Mon Sep 17 00:00:00 2001 From: Umesh Kalappa <ukalappa.m...@gmail.com> Date: Thu, 26 Jun 2025 12:19:41 +0000 Subject: [PATCH 3/4] Made the following changes like a)Refactored the code for proper indent with clang format. b)Emit ADDI for 11 bits unsigned immediate offset . c)Removed the DecodeSImm definition (not used). d)Updated the testcase. --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +- .../RISCV/Disassembler/RISCVDisassembler.cpp | 16 -------- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 13 ++----- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 3 -- llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td | 26 ++++++------- llvm/test/CodeGen/RISCV/xmips-cbop.ll | 38 ++++++++----------- llvm/test/MC/RISCV/xmips-invalid.s | 6 +-- llvm/test/MC/RISCV/xmips-valid.s | 8 ++-- .../TargetParser/RISCVISAInfoTest.cpp | 2 +- 9 files changed, 41 insertions(+), 73 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index edb319e460e35..726b2c6b3f22e 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1527,7 +1527,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidUImm9: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 9) - 1, - "immediate must be a multiple of 9 bytes in the range"); + "immediate offset must be in the range[0-511]"); 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 043aaec11e8c5..01f3388fc7e22 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -535,19 +535,6 @@ 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, @@ -589,9 +576,6 @@ 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" diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 3036b32f706f2..71b9c5fd84d84 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2926,7 +2926,7 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base, } /// Similar to SelectAddrRegImm, except that the offset restricted for -/// nine bits. +/// unsinged nine bits. bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset) { if (SelectAddrFrameIndex(Addr, Base, Offset)) @@ -2936,7 +2936,6 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, 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); @@ -2947,13 +2946,13 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, return true; } - // Handle with 12 bit ofset immediates with ADDI. + // Handle with 12 bit offset with sign bit off with ADDI. + // For Immediate Range [0, 2047] 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)) { + if (isUInt<11>(CVal)) { Base = SDValue(CurDAG->getMachineNode( RISCV::ADDI, DL, VT, Addr.getOperand(0), CurDAG->getSignedTargetConstant(CVal, DL, VT)), @@ -2963,10 +2962,6 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, } } } - // 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); diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index bd28d51b4caef..65c2220e25822 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -45,9 +45,6 @@ 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); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td index 3dcefee9404b4..0c8487c2f5dbe 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td @@ -110,39 +110,39 @@ class SWPFormat<dag outs, dag ins, string opcodestr, string argstr> } // Prefetch format. -let hasSideEffects = 0, mayLoad = 1,mayStore = 1 in +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; + 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 MIPSPREFETCH : Mips_prefetch_ri<(outs),(ins GPR:$rs1, uimm9:$imm9, uimm5:$hint), - "mips.perf", "$hint, ${imm9}(${rs1})">, + 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), + def : Pat<(prefetch (AddrRegImm9 (XLenVT GPR:$rs1), uimm9:$imm9), (i32 1), timm, (i32 1)), - (MIPSPREFETCH GPR:$rs1, uimm9:$imm9, 9)>; + (MIPS_PREFETCH GPR:$rs1, uimm9:$imm9, 9)>; // Prefetch Data Read. - def : Pat<(prefetch(AddrRegImm9(XLenVT GPR:$rs1),uimm9:$imm9), + def : Pat<(prefetch (AddrRegImm9 (XLenVT GPR:$rs1), uimm9:$imm9), (i32 0), timm, (i32 1)), - (MIPSPREFETCH GPR:$rs1, uimm9:$imm9, 8)>; + (MIPS_PREFETCH GPR:$rs1, uimm9:$imm9, 8)>; } let Predicates = [HasVendorXMIPSCMov], hasSideEffects = 0, mayLoad = 0, mayStore = 0, diff --git a/llvm/test/CodeGen/RISCV/xmips-cbop.ll b/llvm/test/CodeGen/RISCV/xmips-cbop.ll index ba95fc9082fa4..291f8ea55ef99 100644 --- a/llvm/test/CodeGen/RISCV/xmips-cbop.ll +++ b/llvm/test/CodeGen/RISCV/xmips-cbop.ll @@ -1,40 +1,32 @@ -; 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) { +define void @prefetch_read(ptr noundef %ptr) nounwind { ; RV32XMIPSPREFETCH-LABEL: prefetch_read: -; RV32XMIPSPREFETCH: mips.perf 8, 511(a0) +; RV32XMIPSPREFETCH: mips.pref 8, 1(a0) ; ; RV64XMIPSPREFETCH-LABEL: prefetch_read: -; RV64XMIPSPREFETCH: mips.perf 8, 511(a0) +; RV64XMIPSPREFETCH: mips.pref 8, 1(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) + %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 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: + +define void @prefetch_write(ptr noundef %ptr) nounwind { ; RV32XMIPSPREFETCH-LABEL: prefetch_write: -; RV32XMIPSPREFETCH: addi a1, a0, 512 -; RV32XMIPSPREFETCH-NEXT: mips.perf 9, 0(a1) +; RV32XMIPSPREFETCH: addi a0, a0, 512 +; RV32XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0) ; ; 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) +; RV64XMIPSPREFETCH: addi a0, a0, 512 +; RV64XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0) +entry: + %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 } diff --git a/llvm/test/MC/RISCV/xmips-invalid.s b/llvm/test/MC/RISCV/xmips-invalid.s index fc7febf115f36..858ad4a4150ec 100644 --- a/llvm/test/MC/RISCV/xmips-invalid.s +++ b/llvm/test/MC/RISCV/xmips-invalid.s @@ -1,13 +1,13 @@ # RUN: not llvm-mc -triple=riscv64 < %s 2>&1 | FileCheck %s -check-prefixes=CHECK-FEATURE # RUN: not llvm-mc -triple=riscv64 -mattr=+xmipslsp,+xmipscmov,+xmipsbcop < %s 2>&1 | FileCheck %s -mips.perf 8, 512(a0) +mips.pref 8, 512(a0) # CHECK: error: invalid operand for instruction -mips.perf 8 +mips.pref 8 # CHECK: error: too few operands for instruction -mips.perf 8, 511(a0) +mips.pref 8, 511(a0) # CHECK-FEATURE: error: instruction requires the following: 'Xmipscbop' (MIPS hardware prefetch) mips.ccmov x0, x1, 0x10 diff --git a/llvm/test/MC/RISCV/xmips-valid.s b/llvm/test/MC/RISCV/xmips-valid.s index 5ced037752cab..fe24b54db8d9e 100644 --- a/llvm/test/MC/RISCV/xmips-valid.s +++ b/llvm/test/MC/RISCV/xmips-valid.s @@ -4,15 +4,15 @@ # 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-INST: mips.pref 8, 511(a0) # CHECK-ENC: encoding: [0x0b,0x04,0xf5,0x1f] -mips.perf 8, 511(a0) +mips.pref 8, 511(a0) # CHECK-DIS: mips.perf 0x8, 0x1ff(a0) -# CHECK-INST: mips.perf 9, 0(a0) +# CHECK-INST: mips.pref 9, 0(a0) # CHECK-ENC: encoding: [0x8b,0x04,0x05,0x00] -mips.perf 9, 0(a0) +mips.pref 9, 0(a0) # CHECK-DIS: mips.perf 0x9, 0x0(a0) diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index b1b4a910650a9..55314d6261fdf 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -1140,9 +1140,9 @@ 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 - xmipscbop 1.0 xsfcease 1.0 xsfmm128t 0.6 xsfmm16t 0.6 >From e1e754df1b24f6f2ad5c65dd013e3b2bad0a699b Mon Sep 17 00:00:00 2001 From: Umesh Kalappa <ukalappa.m...@gmail.com> Date: Fri, 27 Jun 2025 05:36:02 +0000 Subject: [PATCH 4/4] The following changes made to addressed the comments like a)Refactored the code for proper indent with clang format. b)Updated SelectAddrRegImm9 to fall back to already isel exist pattern for ADD. c)Used UTC (utils/update_llc_test_checks.py) to generate the FileCheck CHECKS d)Updated the llvm-mc testcase accordingly. --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +- .../RISCV/Disassembler/RISCVDisassembler.cpp | 3 ++- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 16 ------------ llvm/test/CodeGen/RISCV/xmips-cbop.ll | 25 ++++++++++++------- llvm/test/MC/RISCV/xmips-invalid.s | 4 +-- llvm/test/MC/RISCV/xmips-valid.s | 4 +-- 6 files changed, 23 insertions(+), 31 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 726b2c6b3f22e..d81b2d142455c 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1527,7 +1527,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidUImm9: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 9) - 1, - "immediate offset must be in the range[0-511]"); + "immediate offset must be 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 01f3388fc7e22..78175a25005dc 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -790,7 +790,8 @@ static constexpr DecoderListEntry DecoderList32[]{ {DecoderTableXmipscmov32, {RISCV::FeatureVendorXMIPSCMov}, "MIPS mips.ccmov"}, - {DecoderTableXmipscbop32, {RISCV::FeatureVendorXMIPSCBOP}, + {DecoderTableXmipscbop32, + {RISCV::FeatureVendorXMIPSCBOP}, "MIPS mips.pref"}, {DecoderTableXAndes32, XAndesGroup, "Andes extensions"}, // Standard Extensions diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 71b9c5fd84d84..e6e5df9103d20 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2945,22 +2945,6 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base, Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT); return true; } - - // Handle with 12 bit offset with sign bit off with ADDI. - // For Immediate Range [0, 2047] - else if (Addr.getOpcode() == ISD::ADD && - isa<ConstantSDNode>(Addr.getOperand(1))) { - assert(!isUInt<9>(CVal) && "uimm9 not already handled?"); - - if (isUInt<11>(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; - } - } } Base = Addr; diff --git a/llvm/test/CodeGen/RISCV/xmips-cbop.ll b/llvm/test/CodeGen/RISCV/xmips-cbop.ll index 291f8ea55ef99..edfe57bc5fc90 100644 --- a/llvm/test/CodeGen/RISCV/xmips-cbop.ll +++ b/llvm/test/CodeGen/RISCV/xmips-cbop.ll @@ -1,3 +1,4 @@ +; 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 \ ; RUN: | FileCheck %s -check-prefix=RV32XMIPSPREFETCH ; RUN: llc -mtriple=riscv64 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \ @@ -5,26 +6,32 @@ define void @prefetch_read(ptr noundef %ptr) nounwind { ; RV32XMIPSPREFETCH-LABEL: prefetch_read: -; RV32XMIPSPREFETCH: mips.pref 8, 1(a0) +; RV32XMIPSPREFETCH: # %bb.0: # %entry +; RV32XMIPSPREFETCH-NEXT: mips.pref 8, 1(a0) +; RV32XMIPSPREFETCH-NEXT: ret ; ; RV64XMIPSPREFETCH-LABEL: prefetch_read: -; RV64XMIPSPREFETCH: mips.pref 8, 1(a0) +; 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 - ret void } - + define void @prefetch_write(ptr noundef %ptr) nounwind { ; RV32XMIPSPREFETCH-LABEL: prefetch_write: -; RV32XMIPSPREFETCH: addi a0, a0, 512 -; RV32XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0) +; RV32XMIPSPREFETCH: # %bb.0: +; RV32XMIPSPREFETCH-NEXT: addi a0, a0, 512 +; RV32XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0) +; RV32XMIPSPREFETCH-NEXT: ret ; ; RV64XMIPSPREFETCH-LABEL: prefetch_write: -; RV64XMIPSPREFETCH: addi a0, a0, 512 -; RV64XMIPSPREFETCH-NEXT: mips.pref 9, 0(a0) -entry: +; 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 diff --git a/llvm/test/MC/RISCV/xmips-invalid.s b/llvm/test/MC/RISCV/xmips-invalid.s index 858ad4a4150ec..a17d2e347f8d9 100644 --- a/llvm/test/MC/RISCV/xmips-invalid.s +++ b/llvm/test/MC/RISCV/xmips-invalid.s @@ -1,8 +1,8 @@ # RUN: not llvm-mc -triple=riscv64 < %s 2>&1 | FileCheck %s -check-prefixes=CHECK-FEATURE -# RUN: not llvm-mc -triple=riscv64 -mattr=+xmipslsp,+xmipscmov,+xmipsbcop < %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: invalid operand for instruction +# CHECK: error: immediate offset must be in the range [0, 511] mips.pref 8 # CHECK: error: too few operands for instruction diff --git a/llvm/test/MC/RISCV/xmips-valid.s b/llvm/test/MC/RISCV/xmips-valid.s index fe24b54db8d9e..c5755ee81b499 100644 --- a/llvm/test/MC/RISCV/xmips-valid.s +++ b/llvm/test/MC/RISCV/xmips-valid.s @@ -8,13 +8,13 @@ # CHECK-ENC: encoding: [0x0b,0x04,0xf5,0x1f] mips.pref 8, 511(a0) -# CHECK-DIS: mips.perf 0x8, 0x1ff(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.perf 0x9, 0x0(a0) +# CHECK-DIS: mips.pref 0x9, 0x0(a0) # CHECK-INST: mips.ccmov s0, s1, s2, s3 # CHECK-ENC: encoding: [0x0b,0x34,0x99,0x9e] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits