Skip to content
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

[RISCV] Add MIPS extensions #121394

Open
wants to merge 3 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
6 changes: 6 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ The current vendor extensions supported are:
``experimental-Xqcisls``
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.

``Xmipscmove``
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.

``Xmipslsp``
LLVM implements load/store pair instructions for the `p8700 processor <https://mips.com/products/hardware/p8700/>` by MIPS.

Experimental C Intrinsics
=========================

Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_None;
}

bool isUImm7Lsb000() const {
if (!isImm())
return false;
int64_t Imm;
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
VK == RISCVMCExpr::VK_RISCV_None;
}

bool isUImm8Lsb00() const {
if (!isImm())
return false;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,11 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"SiFive sf.cflush.d.l1 custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,
"SiFive sf.cease custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorMIPSLoadStorePairs,
DecoderTableXmipslsp32,
"MIPS mips.lsp custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorMIPSCMove, DecoderTableXmipscomve32,
"MIPS mips.ccmov custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
DecoderTableXCVbitmanip32,
"CORE-V Bit Manipulation custom opcode table");
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 @@ -308,6 +308,7 @@ enum OperandType : unsigned {
OPERAND_UIMM6_LSB0,
OPERAND_UIMM7,
OPERAND_UIMM7_LSB00,
OPERAND_UIMM7_LSB000,
OPERAND_UIMM8_LSB00,
OPERAND_UIMM8,
OPERAND_UIMM8_LSB000,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ void initializeRISCVMoveMergePass(PassRegistry &);

FunctionPass *createRISCVPushPopOptimizationPass();
void initializeRISCVPushPopOptPass(PassRegistry &);
FunctionPass *createRISCVLoadStoreOptPass();
void initializeRISCVLoadStoreOptPass(PassRegistry &);

FunctionPass *createRISCVZacasABIFixPass();
void initializeRISCVZacasABIFixPass(PassRegistry &);
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1448,3 +1448,18 @@ def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals",
"AllowTaggedGlobals",
"true", "Use an instruction sequence for taking the address of a global "
"that allows a memory tag in the upper address bits">;

def FeatureVendorMIPSCMove : SubtargetFeature<"xmipscmove", "HasVendorMIPSCMove",
"true", "Using CCMov",
[Feature64Bit]>;
def HasVendorMIPSCMove
: Predicate<"Subtarget->useCCMovInsn()">,
AssemblerPredicate<(all_of FeatureVendorMIPSCMove),
"'Xmipscmove' ('mips.ccmov' instruction)">;
def FeatureVendorMIPSLoadStorePairs
: SubtargetFeature<"xmipslsp", "HasMIPSLSP", "true",
"Optimize for hardware load-store bonding">;
def HasVendorMIPSLoadStorePairs
: Predicate<"Subtarget->useLoadStorePairs()">,
AssemblerPredicate<(all_of FeatureVendorMIPSLoadStorePairs),
"'Xmipslsp' (load and store pair instructions)">;
4 changes: 3 additions & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ABS, MVT::i32, Custom);
}

if (!Subtarget.hasVendorXTHeadCondMov())
if (Subtarget.hasVendorMIPSCMove())
setOperationAction(ISD::SELECT, XLenVT, Legal);
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);

static const unsigned FPLegalNodeTypes[] = {
Expand Down
72 changes: 72 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,78 @@ class RVInstJ<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
let Inst{6-0} = opcode.Value;
}

//===----------------------------------------------------------------------===//
// MIPS custom instruction formats
//===----------------------------------------------------------------------===//

// Load double pair format.
class LDPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs1;
bits<5> rd1;
bits<5> rd2;

let Inst{31-27} = rd2;
let Inst{26-23} = imm7{6-3};
let Inst{22-20} = 0b000;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b100;
let Inst{11-7} = rd1;
let Inst{6-0} = OPC_CUSTOM_0.Value;
}

// Load word pair format.
class LWPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs1;
bits<5> rd1;
bits<5> rd2;

let Inst{31-27} = rd2;
let Inst{26-22} = imm7{6-2};
let Inst{21-20} = 0b01;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b100;
let Inst{11-7} = rd1;
let Inst{6-0} = OPC_CUSTOM_0.Value;
}

// Store double pair format.
class SDPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs3;
bits<5> rs2;
bits<5> rs1;

let Inst{31-27} = rs3;
let Inst{26-25} = imm7{6-5};
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b101;
let Inst{11-10} = imm7{4-3};
let Inst{9-0} = 0b0000001011;
}

// Store word pair format.
class SWPFormat<dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
bits<7> imm7;
bits<5> rs3;
bits<5> rs2;
bits<5> rs1;

let Inst{31-27} = rs3;
let Inst{26-25} = imm7{6-5};
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = 0b101;
let Inst{11-9} = imm7{4-2};
let Inst{8-0} = 0b010001011;
}

//===----------------------------------------------------------------------===//
// Instruction classes for .insn directives
//===----------------------------------------------------------------------===//
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 @@ -2489,6 +2489,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_UIMM7_LSB00:
Ok = isShiftedUInt<5, 2>(Imm);
break;
case RISCVOp::OPERAND_UIMM7_LSB000:
Ok = isShiftedUInt<4, 3>(Imm);
break;
case RISCVOp::OPERAND_UIMM8_LSB00:
Ok = isShiftedUInt<6, 2>(Imm);
break;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ def ixlenimm_li_restricted : Operand<XLenVT> {

// Standalone (codegen-only) immleaf patterns.

// A 12-bit signed immediate plus one where the imm range will be -2047~2048.
def simm12_plus1 : ImmLeaf<XLenVT,
[{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;

// A 6-bit constant greater than 32.
def uimm6gt32 : ImmLeaf<XLenVT, [{
return isUInt<6>(Imm) && Imm > 32;
Expand Down Expand Up @@ -2123,6 +2127,7 @@ include "RISCVInstrInfoSFB.td"
include "RISCVInstrInfoXCV.td"
include "RISCVInstrInfoXwch.td"
include "RISCVInstrInfoXqci.td"
include "RISCVInstrInfoXMips.td"

//===----------------------------------------------------------------------===//
// Global ISel
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoC.td
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ def uimm7_lsb00 : RISCVOp,
}];
}

// A 7-bit unsigned immediate where the least significant three bits are zero.
def uimm7_lsb000 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<4, 3>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<7, "Lsb000">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<7>";
let OperandType = "OPERAND_UIMM7_LSB000";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
return false;
return isShiftedUInt<4, 3>(Imm);
}];
}

// A 8-bit unsigned immediate where the least significant two bits are zero.
def uimm8_lsb00 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
Expand Down
82 changes: 82 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//===-- RISCVInstrInfoXMips.td -----------------------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file describes the vendor extensions defined by MIPS.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//

// MIPS extensions
//===----------------------------------------------------------------------===//

let Predicates = [HasVendorMIPSCMove], hasSideEffects = 0, mayLoad = 0, mayStore = 0, DecoderNamespace = "Xmipscomve" in {
def CCMOV : RVInstR4<0b11, 0b011, OPC_CUSTOM_0, (outs GPR:$rd),
(ins GPR:$rs1, GPR:$rs2, GPR:$rs3),
"mips.ccmov", "$rd, $rs2, $rs1, $rs3">,
Sched<[]>;
}

let Predicates = [HasVendorMIPSCMove] in {
def : Pat<(select (XLenVT (setne (XLenVT GPR:$rs2), (XLenVT 0))),
(XLenVT GPR:$rs1), (XLenVT GPR:$rs3)),
(CCMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(select (XLenVT (setne (XLenVT GPR:$x), (XLenVT simm12_plus1:$y))),
(XLenVT GPR:$rs1), (XLenVT GPR:$rs3)),
(CCMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
def : Pat<(select (XLenVT (setne (XLenVT GPR:$x), (XLenVT GPR:$y))),
(XLenVT GPR:$rs1), (XLenVT GPR:$rs3)),
(CCMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
def : Pat<(select (XLenVT (seteq (XLenVT GPR:$rs2), (XLenVT 0))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(select (XLenVT (seteq (XLenVT GPR:$x), (XLenVT simm12_plus1:$y))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
def : Pat<(select (XLenVT (seteq (XLenVT GPR:$x), (XLenVT GPR:$y))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
def : Pat<(select (XLenVT (setuge (XLenVT GPR:$x), (XLenVT GPR:$y))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
def : Pat<(select (XLenVT (setge (XLenVT GPR:$x), (XLenVT GPR:$y))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
def : Pat<(select (XLenVT (setle (XLenVT GPR:$y), (XLenVT GPR:$x))),
(XLenVT GPR:$rs3), (XLenVT GPR:$rs1)),
(CCMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
def : Pat<(select (XLenVT GPR:$rs2), (XLenVT GPR:$rs1), (XLenVT GPR:$rs3)),
(CCMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
}

let Predicates = [HasVendorMIPSLoadStorePairs], hasSideEffects = 0, DecoderNamespace = "Xmipslsp" in {
def LWP : LWPFormat<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7_lsb00:$imm7),
"mips.lwp", "$rd1, $rd2, ${imm7}(${rs1})">,
Sched<[WriteLDW, WriteLDW, ReadMemBase]> {
let mayLoad = 1;
let mayStore = 0;
}
def LDP : LDPFormat<(outs GPR:$rd1, GPR:$rd2), (ins GPR:$rs1, uimm7_lsb000:$imm7),
"mips.ldp", "$rd1, $rd2, ${imm7}(${rs1})">,
Sched<[WriteLDD, WriteLDD, ReadMemBase]> {
let mayLoad = 1;
let mayStore = 0;
}
def SWP : SWPFormat<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7_lsb00:$imm7),
"mips.swp", "$rs2, $rs3, ${imm7}(${rs1})">,
Sched<[WriteSTW, ReadStoreData, ReadStoreData, ReadMemBase]> {
let mayLoad = 0;
let mayStore = 1;
}
def SDP : SDPFormat<(outs), (ins GPR:$rs2, GPR:$rs3, GPR:$rs1, uimm7_lsb000:$imm7),
"mips.sdp", "$rs2, $rs3, ${imm7}(${rs1})">,
Sched<[WriteSTD, ReadStoreData, ReadStoreData, ReadMemBase]> {
let mayLoad = 0;
let mayStore = 1;
}
}
4 changes: 3 additions & 1 deletion llvm/lib/Target/RISCV/RISCVProcessors.td
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ def MIPS_P8700 : RISCVProcessorModel<"mips-p8700",
FeatureStdExtZba,
FeatureStdExtZbb,
FeatureStdExtZifencei,
FeatureStdExtZicsr],
FeatureStdExtZicsr,
FeatureVendorMIPSCMove,
FeatureVendorMIPSLoadStorePairs],
[TuneMIPSP8700]>;

def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32",
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ static cl::opt<unsigned> RISCVMinimumJumpTableEntries(
"riscv-min-jump-table-entries", cl::Hidden,
cl::desc("Set minimum number of entries to use a jump table on RISCV"));

static cl::opt<bool>
UseLoadStorePairsOpt("riscv-load-store-pairs",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this off by default?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, we have not seen benefits on some important applications/benchmarks for us when using this extension with p8700 CPU, so that is why we keep it OFF by default for now.

cl::desc("RISCV: Optimize for load-store bonding"),
cl::init(false), cl::Hidden);

static cl::opt<bool>
UseCCMovInsn("riscv-ccmov", cl::desc("RISCV: Use 'mips.ccmov' instruction"),
cl::init(true), cl::Hidden);

void RISCVSubtarget::anchor() {}

RISCVSubtarget &
Expand Down Expand Up @@ -238,3 +247,11 @@ void RISCVSubtarget::overridePostRASchedPolicy(MachineSchedPolicy &Policy,
Policy.OnlyBottomUp = false;
}
}

bool RISCVSubtarget::useLoadStorePairs() const {
return UseLoadStorePairsOpt && HasMIPSLSP;
}

bool RISCVSubtarget::useCCMovInsn() const {
return UseCCMovInsn && HasVendorMIPSCMove;
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
unsigned getXLen() const {
return is64Bit() ? 64 : 32;
}
bool useLoadStorePairs() const;
bool useCCMovInsn() const;
unsigned getFLen() const {
if (HasStdExtD)
return 64;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,10 @@ class RISCVPassConfig : public TargetPassConfig {
DAG->addMutation(createStoreClusterDAGMutation(
DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true));
}

return DAG;
}

void addIRPasses() override;
bool addPreISel() override;
void addCodeGenPrepare() override;
Expand Down
Loading
Loading