Skip to content

Commit 7b13261

Browse files
committed
[RISCV] Add MIPS extensions
Adding two extensions for MIPS p8700 CPU: 1. cmove (conditional move) 2. lsp (load/store pair) The official product page here: https://mips.com/products/hardware/p8700
1 parent defd0d9 commit 7b13261

27 files changed

+1472
-127
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4977,6 +4977,10 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
49774977
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
49784978
HelpText<"Disable using library calls for save and restore">;
49794979
} // let Flags = [TargetSpecific]
4980+
def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
4981+
def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
4982+
def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
4983+
def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
49804984
let Flags = [TargetSpecific] in {
49814985
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
49824986
HelpText<"Enable use of experimental RISC-V extensions.">;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,21 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
21852185
CmdArgs.push_back(A->getValue());
21862186
}
21872187

2188+
if (Arg *A = Args.getLastArg(options::OPT_mload_store_pairs,
2189+
options::OPT_mno_load_store_pairs)) {
2190+
if (A->getOption().matches(options::OPT_mload_store_pairs)) {
2191+
CmdArgs.push_back("-mllvm");
2192+
CmdArgs.push_back("-riscv-load-store-pairs=1");
2193+
}
2194+
}
2195+
2196+
if (Arg *A = Args.getLastArg(options::OPT_mccmov, options::OPT_mno_ccmov)) {
2197+
if (A->getOption().matches(options::OPT_mno_ccmov)) {
2198+
CmdArgs.push_back("-mllvm");
2199+
CmdArgs.push_back("-riscv-ccmov=0");
2200+
}
2201+
}
2202+
21882203
// Handle -mrvv-vector-bits=<bits>
21892204
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
21902205
StringRef Val = A->getValue();

llvm/docs/RISCVUsage.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,12 @@ The current vendor extensions supported are:
456456
``experimental-Xqcisls``
457457
LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
458458

459+
``Xmipscmove``
460+
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
461+
462+
``Xmipslsp``
463+
LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
464+
459465
Experimental C Intrinsics
460466
=========================
461467

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
877877
VK == RISCVMCExpr::VK_RISCV_None;
878878
}
879879

880+
bool isUImm7Lsb000() const {
881+
if (!isImm())
882+
return false;
883+
int64_t Imm;
884+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
885+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
886+
return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
887+
VK == RISCVMCExpr::VK_RISCV_None;
888+
}
889+
880890
bool isUImm8Lsb00() const {
881891
if (!isImm())
882892
return false;

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ add_llvm_target(RISCVCodeGen
4848
RISCVISelLowering.cpp
4949
RISCVLandingPadSetup.cpp
5050
RISCVMachineFunctionInfo.cpp
51+
RISCVLoadStoreOptimizer.cpp
5152
RISCVMergeBaseOffset.cpp
5253
RISCVOptWInstrs.cpp
5354
RISCVPostRAExpandPseudoInsts.cpp

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ enum OperandType : unsigned {
308308
OPERAND_UIMM6_LSB0,
309309
OPERAND_UIMM7,
310310
OPERAND_UIMM7_LSB00,
311+
OPERAND_UIMM7_LSB000,
311312
OPERAND_UIMM8_LSB00,
312313
OPERAND_UIMM8,
313314
OPERAND_UIMM8_LSB000,

llvm/lib/Target/RISCV/RISCV.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ void initializeRISCVMoveMergePass(PassRegistry &);
8484

8585
FunctionPass *createRISCVPushPopOptimizationPass();
8686
void initializeRISCVPushPopOptPass(PassRegistry &);
87+
FunctionPass *createRISCVLoadStoreOptPass();
88+
void initializeRISCVLoadStoreOptPass(PassRegistry &);
8789

8890
FunctionPass *createRISCVZacasABIFixPass();
8991
void initializeRISCVZacasABIFixPass(PassRegistry &);

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,19 @@ def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()
14231423
def TuneMIPSP8700
14241424
: SubtargetFeature<"mips-p8700", "RISCVProcFamily", "MIPSP8700",
14251425
"MIPS p8700 processor">;
1426+
def FeatureVendorMIPSCMove : SubtargetFeature<"xmipscmove", "HasVendorMIPSCMove",
1427+
"true", "Using CCMov",
1428+
[Feature64Bit]>;
1429+
def HasVendorMIPSCMove
1430+
: Predicate<"Subtarget->useCCMovInsn()">,
1431+
AssemblerPredicate<(all_of FeatureVendorMIPSCMove), "'ccmov' instruction">;
1432+
def FeatureVendorMIPSLoadStorePairs
1433+
: SubtargetFeature<"xmipslsp", "HasMIPSLSP", "true",
1434+
"Optimize for hardware load-store bonding">;
1435+
def HasVendorMIPSLoadStorePairs
1436+
: Predicate<"Subtarget->useLoadStorePairs()">,
1437+
AssemblerPredicate<(all_of FeatureVendorMIPSLoadStorePairs),
1438+
"load and store pair instructions">;
14261439

14271440
def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
14281441
"SiFive 7-Series processors">;

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
409409
setOperationAction(ISD::ABS, MVT::i32, Custom);
410410
}
411411

412-
if (!Subtarget.hasVendorXTHeadCondMov())
412+
if (Subtarget.hasVendorMIPSCMove())
413+
setOperationAction(ISD::SELECT, XLenVT, Legal);
414+
else if (!Subtarget.hasVendorXTHeadCondMov())
413415
setOperationAction(ISD::SELECT, XLenVT, Custom);
414416

415417
static const unsigned FPLegalNodeTypes[] = {

llvm/lib/Target/RISCV/RISCVInstrFormats.td

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,78 @@ class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
514514
let Inst{6-0} = opcode.Value;
515515
}
516516

517+
//===----------------------------------------------------------------------===//
518+
// MIPS custom instruction formats
519+
//===----------------------------------------------------------------------===//
520+
521+
// Load double pair format.
522+
class LDPFormat<dag outs, dag ins, string opcodestr, string argstr>
523+
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
524+
bits<7> imm7;
525+
bits<5> rs1;
526+
bits<5> rd1;
527+
bits<5> rd2;
528+
529+
let Inst{31-27} = rd2;
530+
let Inst{26-23} = imm7{6-3};
531+
let Inst{22-20} = 0b000;
532+
let Inst{19-15} = rs1;
533+
let Inst{14-12} = 0b100;
534+
let Inst{11-7} = rd1;
535+
let Inst{6-0} = 0b0001011;
536+
}
537+
538+
// Load word pair format.
539+
class LWPFormat<dag outs, dag ins, string opcodestr, string argstr>
540+
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
541+
bits<7> imm7;
542+
bits<5> rs1;
543+
bits<5> rd1;
544+
bits<5> rd2;
545+
546+
let Inst{31-27} = rd2;
547+
let Inst{26-22} = imm7{6-2};
548+
let Inst{21-20} = 0b01;
549+
let Inst{19-15} = rs1;
550+
let Inst{14-12} = 0b100;
551+
let Inst{11-7} = rd1;
552+
let Inst{6-0} = 0b0001011;
553+
}
554+
555+
// Store double pair format.
556+
class SDPFormat<dag outs, dag ins, string opcodestr, string argstr>
557+
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
558+
bits<7> imm7;
559+
bits<5> rs3;
560+
bits<5> rs2;
561+
bits<5> rs1;
562+
563+
let Inst{31-27} = rs3;
564+
let Inst{26-25} = imm7{6-5};
565+
let Inst{24-20} = rs2;
566+
let Inst{19-15} = rs1;
567+
let Inst{14-12} = 0b101;
568+
let Inst{11-10} = imm7{4-3};
569+
let Inst{9-0} = 0b0000001011;
570+
}
571+
572+
// Store word pair format.
573+
class SWPFormat<dag outs, dag ins, string opcodestr, string argstr>
574+
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
575+
bits<7> imm7;
576+
bits<5> rs3;
577+
bits<5> rs2;
578+
bits<5> rs1;
579+
580+
let Inst{31-27} = rs3;
581+
let Inst{26-25} = imm7{6-5};
582+
let Inst{24-20} = rs2;
583+
let Inst{19-15} = rs1;
584+
let Inst{14-12} = 0b101;
585+
let Inst{11-9} = imm7{4-2};
586+
let Inst{8-0} = 0b010001011;
587+
}
588+
517589
//===----------------------------------------------------------------------===//
518590
// Instruction classes for .insn directives
519591
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
24892489
case RISCVOp::OPERAND_UIMM7_LSB00:
24902490
Ok = isShiftedUInt<5, 2>(Imm);
24912491
break;
2492+
case RISCVOp::OPERAND_UIMM7_LSB000:
2493+
Ok = isShiftedUInt<4, 3>(Imm);
2494+
break;
24922495
case RISCVOp::OPERAND_UIMM8_LSB00:
24932496
Ok = isShiftedUInt<6, 2>(Imm);
24942497
break;
@@ -2735,6 +2738,46 @@ MachineInstr *RISCVInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
27352738
.setMIFlags(MemI.getFlags());
27362739
}
27372740

2741+
bool RISCVInstrInfo::isPairableLdStInstOpc(unsigned Opc) {
2742+
switch (Opc) {
2743+
default:
2744+
return false;
2745+
case RISCV::SH:
2746+
case RISCV::LH:
2747+
case RISCV::LHU:
2748+
case RISCV::SW:
2749+
case RISCV::FSW:
2750+
case RISCV::LW:
2751+
case RISCV::FLW:
2752+
case RISCV::SD:
2753+
case RISCV::FSD:
2754+
case RISCV::LD:
2755+
case RISCV::FLD:
2756+
return true;
2757+
}
2758+
}
2759+
2760+
bool RISCVInstrInfo::isLdStSafeToPair(const MachineInstr &LdSt,
2761+
const TargetRegisterInfo *TRI) {
2762+
// If this is a volatile load/store, don't mess with it.
2763+
if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
2764+
return false;
2765+
2766+
if (LdSt.getOperand(1).isFI())
2767+
return true;
2768+
2769+
assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
2770+
// Can't cluster if the instruction modifies the base register
2771+
// or it is update form. e.g. ld x5,8(x5)
2772+
if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
2773+
return false;
2774+
2775+
if (!LdSt.getOperand(2).isImm())
2776+
return false;
2777+
2778+
return true;
2779+
}
2780+
27382781
bool RISCVInstrInfo::getMemOperandsWithOffsetWidth(
27392782
const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
27402783
int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
301301
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
302302
analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
303303

304+
/// Return true if pairing the given load or store may be paired with another.
305+
static bool isPairableLdStInstOpc(unsigned Opc);
306+
307+
static bool isLdStSafeToPair(const MachineInstr &LdSt,
308+
const TargetRegisterInfo *TRI);
309+
304310
protected:
305311
const RISCVSubtarget &STI;
306312

0 commit comments

Comments
 (0)