Skip to content

Commit f833498

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 1d51546 commit f833498

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
@@ -4963,6 +4963,10 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
49634963
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
49644964
HelpText<"Disable using library calls for save and restore">;
49654965
} // let Flags = [TargetSpecific]
4966+
def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
4967+
def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
4968+
def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
4969+
def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
49664970
let Flags = [TargetSpecific] in {
49674971
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
49684972
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
@@ -2167,6 +2167,21 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
21672167
CmdArgs.push_back(A->getValue());
21682168
}
21692169

2170+
if (Arg *A = Args.getLastArg(options::OPT_mload_store_pairs,
2171+
options::OPT_mno_load_store_pairs)) {
2172+
if (A->getOption().matches(options::OPT_mload_store_pairs)) {
2173+
CmdArgs.push_back("-mllvm");
2174+
CmdArgs.push_back("-riscv-load-store-pairs=1");
2175+
}
2176+
}
2177+
2178+
if (Arg *A = Args.getLastArg(options::OPT_mccmov, options::OPT_mno_ccmov)) {
2179+
if (A->getOption().matches(options::OPT_mno_ccmov)) {
2180+
CmdArgs.push_back("-mllvm");
2181+
CmdArgs.push_back("-riscv-ccmov=0");
2182+
}
2183+
}
2184+
21702185
// Handle -mrvv-vector-bits=<bits>
21712186
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
21722187
StringRef Val = A->getValue();

llvm/docs/RISCVUsage.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ The current vendor extensions supported are:
444444
``experimental-Xqcisls``
445445
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.
446446

447+
``Xmipscmove``
448+
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
449+
450+
``Xmipslsp``
451+
LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
452+
447453
Experimental C Intrinsics
448454
=========================
449455

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

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

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

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ add_llvm_target(RISCVCodeGen
4747
RISCVISelLowering.cpp
4848
RISCVLandingPadSetup.cpp
4949
RISCVMachineFunctionInfo.cpp
50+
RISCVLoadStoreOptimizer.cpp
5051
RISCVMergeBaseOffset.cpp
5152
RISCVOptWInstrs.cpp
5253
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
@@ -1395,6 +1395,19 @@ def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()
13951395
def TuneMIPSP8700
13961396
: SubtargetFeature<"mips-p8700", "RISCVProcFamily", "MIPSP8700",
13971397
"MIPS p8700 processor">;
1398+
def FeatureVendorMIPSCMove : SubtargetFeature<"xmipscmove", "HasVendorMIPSCMove",
1399+
"true", "Using CCMov",
1400+
[Feature64Bit]>;
1401+
def HasVendorMIPSCMove
1402+
: Predicate<"Subtarget->useCCMovInsn()">,
1403+
AssemblerPredicate<(all_of FeatureVendorMIPSCMove), "'ccmov' instruction">;
1404+
def FeatureVendorMIPSLoadStorePairs
1405+
: SubtargetFeature<"xmipslsp", "HasMIPSLSP", "true",
1406+
"Optimize for hardware load-store bonding">;
1407+
def HasVendorMIPSLoadStorePairs
1408+
: Predicate<"Subtarget->useLoadStorePairs()">,
1409+
AssemblerPredicate<(all_of FeatureVendorMIPSLoadStorePairs),
1410+
"load and store pair instructions">;
13981411

13991412
def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
14001413
"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
@@ -2488,6 +2488,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
24882488
case RISCVOp::OPERAND_UIMM7_LSB00:
24892489
Ok = isShiftedUInt<5, 2>(Imm);
24902490
break;
2491+
case RISCVOp::OPERAND_UIMM7_LSB000:
2492+
Ok = isShiftedUInt<4, 3>(Imm);
2493+
break;
24912494
case RISCVOp::OPERAND_UIMM8_LSB00:
24922495
Ok = isShiftedUInt<6, 2>(Imm);
24932496
break;
@@ -2734,6 +2737,46 @@ MachineInstr *RISCVInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
27342737
.setMIFlags(MemI.getFlags());
27352738
}
27362739

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