Skip to content

Commit a689fb2

Browse files
djtodorodjtodoro
authored andcommitted
[RISCV] Add MIPS extensions
Introduce MIPS extensions by adding: 1) ccmov (+xmipscmov) 2) load/store pairs (+xmipslsp) The -mload-store-pairs imply l[w|d]p and s[w|d]p usage. The `ccmov` feature is ON by default, so we introduce an option for disabling the feature - `-mno-ccmov`. co-authored by Dragan Mladjenovic <[email protected]> co-authored by Jovan Dmitrović <[email protected]>
1 parent f543ef5 commit a689fb2

28 files changed

+1490
-142
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4937,6 +4937,10 @@ def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
49374937
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
49384938
HelpText<"Disable using library calls for save and restore">;
49394939
} // let Flags = [TargetSpecific]
4940+
def mload_store_pairs : Flag<["-"], "mload-store-pairs">, Group<m_riscv_Features_Group>;
4941+
def mno_load_store_pairs : Flag<["-"], "mno-load-store-pairs">, Group<m_riscv_Features_Group>;
4942+
def mccmov : Flag<["-"], "mccmov">, Group<m_riscv_Features_Group>;
4943+
def mno_ccmov : Flag<["-"], "mno-ccmov">, Group<m_riscv_Features_Group>;
49404944
let Flags = [TargetSpecific] in {
49414945
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
49424946
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
@@ -2164,6 +2164,21 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
21642164
CmdArgs.push_back(A->getValue());
21652165
}
21662166

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

llvm/docs/RISCVUsage.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ The current vendor extensions supported are:
423423
``Xwchc``
424424
LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".
425425

426+
``xmipscmove``
427+
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
428+
429+
``xmipslsp``
430+
LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.
431+
426432
Experimental C Intrinsics
427433
=========================
428434

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
855855
VK == RISCVMCExpr::VK_RISCV_None;
856856
}
857857

858+
bool isUImm7Lsb000() const {
859+
if (!isImm())
860+
return false;
861+
int64_t Imm;
862+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
863+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
864+
return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
865+
VK == RISCVMCExpr::VK_RISCV_None;
866+
}
867+
858868
bool isUImm8Lsb00() const {
859869
if (!isImm())
860870
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
@@ -300,6 +300,7 @@ enum OperandType : unsigned {
300300
OPERAND_UIMM6_LSB0,
301301
OPERAND_UIMM7,
302302
OPERAND_UIMM7_LSB00,
303+
OPERAND_UIMM7_LSB000,
303304
OPERAND_UIMM8_LSB00,
304305
OPERAND_UIMM8,
305306
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
@@ -1446,6 +1446,19 @@ def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()
14461446
def TuneMIPSP8700
14471447
: SubtargetFeature<"mips-p8700", "RISCVProcFamily", "Others",
14481448
"MIPS p8700 processor">;
1449+
def FeatureMIPSCMov : SubtargetFeature<"xmipscmov", "HasMIPSCMov",
1450+
"true", "Using CCMov",
1451+
[Feature64Bit]>;
1452+
def UsesMIPSCMov
1453+
: Predicate<"Subtarget->useCCMovInsn()">,
1454+
AssemblerPredicate<(all_of FeatureMIPSCMov), "'ccmov' instruction">;
1455+
def FeatureMIPSLoadStorePairs
1456+
: SubtargetFeature<"xmipslsp", "HasMIPSLSP", "true",
1457+
"Optimize for hardware load-store bonding">;
1458+
def UsesMIPSLoadStorePairs
1459+
: Predicate<"Subtarget->useLoadStorePairs()">,
1460+
AssemblerPredicate<(all_of FeatureMIPSLoadStorePairs),
1461+
"load and store pair instructions">;
14491462

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

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

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

411-
if (!Subtarget.hasVendorXTHeadCondMov())
411+
if (Subtarget.hasMIPSCMov())
412+
setOperationAction(ISD::SELECT, XLenVT, Legal);
413+
else if (!Subtarget.hasVendorXTHeadCondMov())
412414
setOperationAction(ISD::SELECT, XLenVT, Custom);
413415

414416
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
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)