Skip to content

Commit 2afea72

Browse files
authored
[RISCV] Codegen support for XCVmem extension (#76916)
All post-Increment load/store, register-register load/store spec: https://github.com/openhwgroup/cv32e40p/blob/master/docs/source/instruction_set_extensions.rst Contributors: @CharKeaney, @jeremybennett, @lewis-revill, @NandniJamnadas, @PaoloS02, @serkm, @simonpcook, @xingmingjie, @realqhc
1 parent 2981f3a commit 2afea72

File tree

6 files changed

+446
-2
lines changed

6 files changed

+446
-2
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
12451245
}
12461246

12471247
void addRegRegOperands(MCInst &Inst, unsigned N) const {
1248-
assert(N == 1 && "Invalid number of operands!");
1248+
assert(N == 2 && "Invalid number of operands!");
12491249
Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
12501250
Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
12511251
}

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,67 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
15271527
case ISD::LOAD: {
15281528
if (tryIndexedLoad(Node))
15291529
return;
1530+
1531+
if (Subtarget->hasVendorXCVmem()) {
1532+
// We match post-incrementing load here
1533+
LoadSDNode *Load = cast<LoadSDNode>(Node);
1534+
if (Load->getAddressingMode() != ISD::POST_INC)
1535+
break;
1536+
1537+
SDValue Chain = Node->getOperand(0);
1538+
SDValue Base = Node->getOperand(1);
1539+
SDValue Offset = Node->getOperand(2);
1540+
1541+
bool Simm12 = false;
1542+
bool SignExtend = Load->getExtensionType() == ISD::SEXTLOAD;
1543+
1544+
if (auto ConstantOffset = dyn_cast<ConstantSDNode>(Offset)) {
1545+
int ConstantVal = ConstantOffset->getSExtValue();
1546+
Simm12 = isInt<12>(ConstantVal);
1547+
if (Simm12)
1548+
Offset = CurDAG->getTargetConstant(ConstantVal, SDLoc(Offset),
1549+
Offset.getValueType());
1550+
}
1551+
1552+
unsigned Opcode = 0;
1553+
switch (Load->getMemoryVT().getSimpleVT().SimpleTy) {
1554+
case MVT::i8:
1555+
if (Simm12 && SignExtend)
1556+
Opcode = RISCV::CV_LB_ri_inc;
1557+
else if (Simm12 && !SignExtend)
1558+
Opcode = RISCV::CV_LBU_ri_inc;
1559+
else if (!Simm12 && SignExtend)
1560+
Opcode = RISCV::CV_LB_rr_inc;
1561+
else
1562+
Opcode = RISCV::CV_LBU_rr_inc;
1563+
break;
1564+
case MVT::i16:
1565+
if (Simm12 && SignExtend)
1566+
Opcode = RISCV::CV_LH_ri_inc;
1567+
else if (Simm12 && !SignExtend)
1568+
Opcode = RISCV::CV_LHU_ri_inc;
1569+
else if (!Simm12 && SignExtend)
1570+
Opcode = RISCV::CV_LH_rr_inc;
1571+
else
1572+
Opcode = RISCV::CV_LHU_rr_inc;
1573+
break;
1574+
case MVT::i32:
1575+
if (Simm12)
1576+
Opcode = RISCV::CV_LW_ri_inc;
1577+
else
1578+
Opcode = RISCV::CV_LW_rr_inc;
1579+
break;
1580+
default:
1581+
break;
1582+
}
1583+
if (!Opcode)
1584+
break;
1585+
1586+
ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, XLenVT, XLenVT,
1587+
Chain.getSimpleValueType(), Base,
1588+
Offset, Chain));
1589+
return;
1590+
}
15301591
break;
15311592
}
15321593
case ISD::INTRINSIC_WO_CHAIN: {
@@ -2669,6 +2730,19 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
26692730
return true;
26702731
}
26712732

2733+
bool RISCVDAGToDAGISel::SelectAddrRegReg(SDValue Addr, SDValue &Base,
2734+
SDValue &Offset) {
2735+
if (Addr.getOpcode() != ISD::ADD)
2736+
return false;
2737+
2738+
if (isa<ConstantSDNode>(Addr.getOperand(1)))
2739+
return false;
2740+
2741+
Base = Addr.getOperand(1);
2742+
Offset = Addr.getOperand(0);
2743+
return true;
2744+
}
2745+
26722746
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
26732747
SDValue &ShAmt) {
26742748
ShAmt = N;

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
7878
return false;
7979
}
8080

81+
bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset);
82+
8183
bool tryShrinkShlLogicImm(SDNode *Node);
8284
bool trySignedBitfieldExtract(SDNode *Node);
8385
bool tryIndexedLoad(SDNode *Node);

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,16 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
14511451
}
14521452
}
14531453

1454+
if (Subtarget.hasVendorXCVmem()) {
1455+
setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
1456+
setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
1457+
setIndexedLoadAction(ISD::POST_INC, MVT::i32, Legal);
1458+
1459+
setIndexedStoreAction(ISD::POST_INC, MVT::i8, Legal);
1460+
setIndexedStoreAction(ISD::POST_INC, MVT::i16, Legal);
1461+
setIndexedStoreAction(ISD::POST_INC, MVT::i32, Legal);
1462+
}
1463+
14541464
// Function alignments.
14551465
const Align FunctionAlignment(Subtarget.hasStdExtCOrZca() ? 2 : 4);
14561466
setMinFunctionAlignment(FunctionAlignment);
@@ -20933,6 +20943,26 @@ bool RISCVTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
2093320943
SDValue &Offset,
2093420944
ISD::MemIndexedMode &AM,
2093520945
SelectionDAG &DAG) const {
20946+
if (Subtarget.hasVendorXCVmem()) {
20947+
if (Op->getOpcode() != ISD::ADD)
20948+
return false;
20949+
20950+
if (LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(N))
20951+
Base = LS->getBasePtr();
20952+
else
20953+
return false;
20954+
20955+
if (Base == Op->getOperand(0))
20956+
Offset = Op->getOperand(1);
20957+
else if (Base == Op->getOperand(1))
20958+
Offset = Op->getOperand(0);
20959+
else
20960+
return false;
20961+
20962+
AM = ISD::POST_INC;
20963+
return true;
20964+
}
20965+
2093620966
EVT VT;
2093720967
SDValue Ptr;
2093820968
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {

llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,11 +512,13 @@ def CVrrAsmOperand : AsmOperandClass {
512512
let DiagnosticType = "InvalidRegReg";
513513
}
514514

515-
def CVrr : Operand<OtherVT> {
515+
def CVrr : Operand<i32>,
516+
ComplexPattern<i32, 2, "SelectAddrRegReg",[]> {
516517
let ParserMatchClass = CVrrAsmOperand;
517518
let EncoderMethod = "getRegReg";
518519
let DecoderMethod = "decodeRegReg";
519520
let PrintMethod = "printRegReg";
521+
let MIOperandInfo = (ops GPR:$base, GPR:$offset);
520522
}
521523

522524
class CVLoad_ri_inc<bits<3> funct3, string opcodestr>
@@ -659,6 +661,47 @@ let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0,
659661
def CV_ELW : CVLoad_ri<0b011, "cv.elw">;
660662
}
661663

664+
//===----------------------------------------------------------------------===//
665+
// Patterns for load & store operations
666+
//===----------------------------------------------------------------------===//
667+
class CVLdrrPat<PatFrag LoadOp, RVInst Inst>
668+
: Pat<(XLenVT (LoadOp CVrr:$regreg)),
669+
(Inst CVrr:$regreg)>;
670+
671+
class CVStriPat<PatFrag StoreOp, RVInst Inst>
672+
: Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, simm12:$imm12),
673+
(Inst GPR:$rs2, GPR:$rs1, simm12:$imm12)>;
674+
675+
class CVStrriPat<PatFrag StoreOp, RVInst Inst>
676+
: Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, GPR:$rs3),
677+
(Inst GPR:$rs2, GPR:$rs1, GPR:$rs3)>;
678+
679+
class CVStrrPat<PatFrag StoreOp, RVInst Inst>
680+
: Pat<(StoreOp (XLenVT GPR:$rs2), CVrr:$regreg),
681+
(Inst GPR:$rs2, CVrr:$regreg)>;
682+
683+
let Predicates = [HasVendorXCVmem, IsRV32], AddedComplexity = 1 in {
684+
def : CVLdrrPat<sextloadi8, CV_LB_rr>;
685+
def : CVLdrrPat<zextloadi8, CV_LBU_rr>;
686+
def : CVLdrrPat<extloadi8, CV_LBU_rr>;
687+
def : CVLdrrPat<sextloadi16, CV_LH_rr>;
688+
def : CVLdrrPat<zextloadi16, CV_LHU_rr>;
689+
def : CVLdrrPat<extloadi16, CV_LHU_rr>;
690+
def : CVLdrrPat<load, CV_LW_rr>;
691+
692+
def : CVStriPat<post_truncsti8, CV_SB_ri_inc>;
693+
def : CVStriPat<post_truncsti16, CV_SH_ri_inc>;
694+
def : CVStriPat<post_store, CV_SW_ri_inc>;
695+
696+
def : CVStrriPat<post_truncsti8, CV_SB_rr_inc>;
697+
def : CVStrriPat<post_truncsti16, CV_SH_ri_inc>;
698+
def : CVStrriPat<post_store, CV_SW_rr_inc>;
699+
700+
def : CVStrrPat<truncstorei8, CV_SB_rr>;
701+
def : CVStrrPat<truncstorei16, CV_SH_rr>;
702+
def : CVStrrPat<store, CV_SW_rr>;
703+
}
704+
662705
def cv_tuimm2 : TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]>;
663706
def cv_tuimm5 : TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
664707
def cv_uimm10 : ImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;

0 commit comments

Comments
 (0)