Skip to content

Commit cf75ef4

Browse files
gonglingqinSixWeining
authored andcommitted
[LoongArch] Add codegen support for ISD::ROTL and ISD::ROTR
Differential Revision: https://reviews.llvm.org/D131231
1 parent 9fa59e7 commit cf75ef4

File tree

4 files changed

+667
-0
lines changed

4 files changed

+667
-0
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
5252
setOperationAction(ISD::SRA_PARTS, GRLenVT, Custom);
5353
setOperationAction(ISD::SRL_PARTS, GRLenVT, Custom);
5454
setOperationAction(ISD::FP_TO_SINT, GRLenVT, Custom);
55+
setOperationAction(ISD::ROTL, GRLenVT, Expand);
5556

5657
setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom);
5758

@@ -65,6 +66,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
6566
setOperationAction(ISD::SRL, MVT::i32, Custom);
6667
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
6768
setOperationAction(ISD::BITCAST, MVT::i32, Custom);
69+
setOperationAction(ISD::ROTR, MVT::i32, Custom);
70+
setOperationAction(ISD::ROTL, MVT::i32, Custom);
6871
if (Subtarget.hasBasicF() && !Subtarget.hasBasicD())
6972
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
7073
}
@@ -363,6 +366,10 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
363366
return LoongArchISD::SRA_W;
364367
case ISD::SRL:
365368
return LoongArchISD::SRL_W;
369+
case ISD::ROTR:
370+
return LoongArchISD::ROTR_W;
371+
case ISD::ROTL:
372+
return LoongArchISD::ROTL_W;
366373
}
367374
}
368375

@@ -391,13 +398,21 @@ void LoongArchTargetLowering::ReplaceNodeResults(
391398
case ISD::SHL:
392399
case ISD::SRA:
393400
case ISD::SRL:
401+
case ISD::ROTR:
394402
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
395403
"Unexpected custom legalisation");
396404
if (N->getOperand(1).getOpcode() != ISD::Constant) {
397405
Results.push_back(customLegalizeToWOp(N, DAG));
398406
break;
399407
}
400408
break;
409+
case ISD::ROTL:
410+
ConstantSDNode *CN;
411+
if ((CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))) {
412+
Results.push_back(customLegalizeToWOp(N, DAG));
413+
break;
414+
}
415+
break;
401416
case ISD::FP_TO_SINT: {
402417
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
403418
"Unexpected custom legalisation");
@@ -882,6 +897,8 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
882897
NODE_NAME_CASE(FTINT)
883898
NODE_NAME_CASE(REVB_2H)
884899
NODE_NAME_CASE(REVB_2W)
900+
NODE_NAME_CASE(ROTR_W)
901+
NODE_NAME_CASE(ROTL_W)
885902
}
886903
#undef NODE_NAME_CASE
887904
return nullptr;

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ enum NodeType : unsigned {
3535
SRA_W,
3636
SRL_W,
3737

38+
ROTL_W,
39+
ROTR_W,
40+
3841
// FPR<->GPR transfer operations
3942
MOVGR2FR_W_LA64,
4043
MOVFR2GR_S_LA64,

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

+18
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ def loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone,
5151
def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
5252
def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
5353
def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
54+
def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
55+
def loongarch_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>;
5456
def loongarch_bstrins
5557
: SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
5658
def loongarch_bstrpick
@@ -178,6 +180,12 @@ def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>;
178180
def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;
179181
def fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>;
180182

183+
// Return an immediate subtracted from 32.
184+
def ImmSubFrom32 : SDNodeXForm<imm, [{
185+
return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
186+
N->getValueType(0));
187+
}]>;
188+
181189
def CallSymbol: AsmOperandClass {
182190
let Name = "CallSymbol";
183191
let RenderMethod = "addImmOperands";
@@ -626,6 +634,8 @@ def : PatGprGpr<urem, MOD_WU>;
626634
def : PatGprGpr<mul, MUL_W>;
627635
def : PatGprGpr<mulhs, MULH_W>;
628636
def : PatGprGpr<mulhu, MULH_WU>;
637+
def : PatGprGpr<rotr, ROTR_W>;
638+
def : PatGprImm<rotr, ROTRI_W, uimm5>;
629639
} // Predicates = [IsLA32]
630640

631641
let Predicates = [IsLA64] in {
@@ -639,6 +649,14 @@ def : PatGprGpr<sdiv, DIV_D>;
639649
def : PatGprGpr<udiv, DIV_DU>;
640650
def : PatGprGpr<srem, MOD_D>;
641651
def : PatGprGpr<urem, MOD_DU>;
652+
def : PatGprGpr<rotr, ROTR_D>;
653+
def : PatGprGpr<loongarch_rotr_w, ROTR_W>;
654+
def : PatGprImm<rotr, ROTRI_D, uimm6>;
655+
def : PatGprImm_32<rotr, ROTRI_W, uimm5>;
656+
def : Pat<(loongarch_rotl_w GPR:$rj, uimm5:$imm),
657+
(ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
658+
def : Pat<(sext_inreg (loongarch_rotl_w GPR:$rj, uimm5:$imm), i32),
659+
(ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>;
642660
// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the
643661
// product are used.
644662
def : PatGprGpr<mul, MUL_D>;

0 commit comments

Comments
 (0)