Skip to content

Commit 26f3a72

Browse files
committed
[RISCV] Codegen support for XCVmem extension
All post-Increment load/store, register-register load/store spec: https://github.com/openhwgroup/cv32e40p/blob/master/docs/source/instruction_set_extensions.rst
1 parent 80889ae commit 26f3a72

File tree

6 files changed

+446
-2
lines changed

6 files changed

+446
-2
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
12101210
}
12111211

12121212
void addRegRegOperands(MCInst &Inst, unsigned N) const {
1213-
assert(N == 1 && "Invalid number of operands!");
1213+
assert(N == 2 && "Invalid number of operands!");
12141214
Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
12151215
Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
12161216
}

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,67 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
14171417
case ISD::LOAD: {
14181418
if (tryIndexedLoad(Node))
14191419
return;
1420+
1421+
if (Subtarget->hasVendorXCVmem()) {
1422+
// We match post-incrementing load here
1423+
LoadSDNode *Load = cast<LoadSDNode>(Node);
1424+
if (Load->getAddressingMode() != ISD::POST_INC)
1425+
break;
1426+
1427+
SDValue Chain = Node->getOperand(0);
1428+
SDValue Base = Node->getOperand(1);
1429+
SDValue Offset = Node->getOperand(2);
1430+
1431+
bool Simm12 = false;
1432+
bool SignExtend = Load->getExtensionType() == ISD::SEXTLOAD;
1433+
1434+
if (auto ConstantOffset = dyn_cast<ConstantSDNode>(Offset)) {
1435+
int ConstantVal = ConstantOffset->getSExtValue();
1436+
Simm12 = isInt<12>(ConstantVal);
1437+
if (Simm12)
1438+
Offset = CurDAG->getTargetConstant(ConstantVal, SDLoc(Offset),
1439+
Offset.getValueType());
1440+
}
1441+
1442+
unsigned Opcode = 0;
1443+
switch (Load->getMemoryVT().getSimpleVT().SimpleTy) {
1444+
case MVT::i8:
1445+
if (Simm12 && SignExtend)
1446+
Opcode = RISCV::CV_LB_ri_inc;
1447+
else if (Simm12 && !SignExtend)
1448+
Opcode = RISCV::CV_LBU_ri_inc;
1449+
else if (!Simm12 && SignExtend)
1450+
Opcode = RISCV::CV_LB_rr_inc;
1451+
else
1452+
Opcode = RISCV::CV_LBU_rr_inc;
1453+
break;
1454+
case MVT::i16:
1455+
if (Simm12 && SignExtend)
1456+
Opcode = RISCV::CV_LH_ri_inc;
1457+
else if (Simm12 && !SignExtend)
1458+
Opcode = RISCV::CV_LHU_ri_inc;
1459+
else if (!Simm12 && SignExtend)
1460+
Opcode = RISCV::CV_LH_rr_inc;
1461+
else
1462+
Opcode = RISCV::CV_LHU_rr_inc;
1463+
break;
1464+
case MVT::i32:
1465+
if (Simm12)
1466+
Opcode = RISCV::CV_LW_ri_inc;
1467+
else
1468+
Opcode = RISCV::CV_LW_rr_inc;
1469+
break;
1470+
default:
1471+
break;
1472+
}
1473+
if (!Opcode)
1474+
break;
1475+
1476+
ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, XLenVT, XLenVT,
1477+
Chain.getSimpleValueType(), Base,
1478+
Offset, Chain));
1479+
return;
1480+
}
14201481
break;
14211482
}
14221483
case ISD::INTRINSIC_WO_CHAIN: {
@@ -2544,6 +2605,19 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
25442605
return true;
25452606
}
25462607

2608+
bool RISCVDAGToDAGISel::SelectAddrRegReg(SDValue Addr, SDValue &Base,
2609+
SDValue &Offset) {
2610+
if (Addr.getOpcode() != ISD::ADD)
2611+
return false;
2612+
2613+
if (isa<ConstantSDNode>(Addr.getOperand(1)))
2614+
return false;
2615+
2616+
Base = Addr.getOperand(1);
2617+
Offset = Addr.getOperand(0);
2618+
return true;
2619+
}
2620+
25472621
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
25482622
SDValue &ShAmt) {
25492623
ShAmt = N;

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
8080
return false;
8181
}
8282

83+
bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset);
84+
8385
bool tryShrinkShlLogicImm(SDNode *Node);
8486
bool trySignedBitfieldExtract(SDNode *Node);
8587
bool tryIndexedLoad(SDNode *Node);

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,16 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
13661366
}
13671367
}
13681368

1369+
if (Subtarget.hasVendorXCVmem()) {
1370+
setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
1371+
setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
1372+
setIndexedLoadAction(ISD::POST_INC, MVT::i32, Legal);
1373+
1374+
setIndexedStoreAction(ISD::POST_INC, MVT::i8, Legal);
1375+
setIndexedStoreAction(ISD::POST_INC, MVT::i16, Legal);
1376+
setIndexedStoreAction(ISD::POST_INC, MVT::i32, Legal);
1377+
}
1378+
13691379
// Function alignments.
13701380
const Align FunctionAlignment(Subtarget.hasStdExtCOrZca() ? 2 : 4);
13711381
setMinFunctionAlignment(FunctionAlignment);
@@ -19324,6 +19334,26 @@ bool RISCVTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1932419334
SDValue &Offset,
1932519335
ISD::MemIndexedMode &AM,
1932619336
SelectionDAG &DAG) const {
19337+
if (Subtarget.hasVendorXCVmem()) {
19338+
if (Op->getOpcode() != ISD::ADD)
19339+
return false;
19340+
19341+
if (LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(N))
19342+
Base = LS->getBasePtr();
19343+
else
19344+
return false;
19345+
19346+
if (Base == Op->getOperand(0))
19347+
Offset = Op->getOperand(1);
19348+
else if (Base == Op->getOperand(1))
19349+
Offset = Op->getOperand(0);
19350+
else
19351+
return false;
19352+
19353+
AM = ISD::POST_INC;
19354+
return true;
19355+
}
19356+
1932719357
EVT VT;
1932819358
SDValue Ptr;
1932919359
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {

llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td

+44-1
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)