@@ -601,8 +601,16 @@ bool RISCVDAGToDAGISel::tryShrinkShlLogicImm(SDNode *Node) {
601601}
602602
603603bool RISCVDAGToDAGISel::trySignedBitfieldExtract (SDNode *Node) {
604- // Only supported with XTHeadBb/XAndesPerf at the moment.
605- if (!Subtarget->hasVendorXTHeadBb () && !Subtarget->hasVendorXAndesPerf ())
604+ unsigned Opc;
605+
606+ if (Subtarget->hasVendorXTHeadBb ())
607+ Opc = RISCV::TH_EXT;
608+ else if (Subtarget->hasVendorXAndesPerf ())
609+ Opc = RISCV::NDS_BFOS;
610+ else if (Subtarget->hasVendorXqcibm ())
611+ Opc = RISCV::QC_EXT;
612+ else
613+ // Only supported with XTHeadBb/XAndesPerf/Xqcibm at the moment.
606614 return false ;
607615
608616 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand (1 ));
@@ -615,8 +623,12 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
615623
616624 auto BitfieldExtract = [&](SDValue N0, unsigned Msb, unsigned Lsb,
617625 const SDLoc &DL, MVT VT) {
618- unsigned Opc =
619- Subtarget->hasVendorXTHeadBb () ? RISCV::TH_EXT : RISCV::NDS_BFOS;
626+ if (Opc == RISCV::QC_EXT) {
627+ // QC.EXT X, width, shamt
628+ // shamt is the same as Lsb
629+ // width is the number of bits to extract from the Lsb
630+ Msb = Msb - Lsb + 1 ;
631+ }
620632 return CurDAG->getMachineNode (Opc, DL, VT, N0.getOperand (0 ),
621633 CurDAG->getTargetConstant (Msb, DL, VT),
622634 CurDAG->getTargetConstant (Lsb, DL, VT));
@@ -627,7 +639,7 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
627639 const unsigned RightShAmt = N1C->getZExtValue ();
628640
629641 // Transform (sra (shl X, C1) C2) with C1 < C2
630- // -> (TH.EXT X, msb, lsb)
642+ // -> (SignedBitfieldExtract X, msb, lsb)
631643 if (N0.getOpcode () == ISD::SHL) {
632644 auto *N01C = dyn_cast<ConstantSDNode>(N0->getOperand (1 ));
633645 if (!N01C)
@@ -643,13 +655,13 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
643655 const unsigned Msb = MsbPlusOne - 1 ;
644656 const unsigned Lsb = RightShAmt - LeftShAmt;
645657
646- SDNode *TH_EXT = BitfieldExtract (N0, Msb, Lsb, DL, VT);
647- ReplaceNode (Node, TH_EXT );
658+ SDNode *Sbe = BitfieldExtract (N0, Msb, Lsb, DL, VT);
659+ ReplaceNode (Node, Sbe );
648660 return true ;
649661 }
650662
651663 // Transform (sra (sext_inreg X, _), C) ->
652- // (TH.EXT X, msb, lsb)
664+ // (SignedBitfieldExtract X, msb, lsb)
653665 if (N0.getOpcode () == ISD::SIGN_EXTEND_INREG) {
654666 unsigned ExtSize =
655667 cast<VTSDNode>(N0.getOperand (1 ))->getVT ().getSizeInBits ();
@@ -663,8 +675,8 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
663675 // the X[Msb] bit and sign-extend it.
664676 const unsigned Lsb = RightShAmt > Msb ? Msb : RightShAmt;
665677
666- SDNode *TH_EXT = BitfieldExtract (N0, Msb, Lsb, DL, VT);
667- ReplaceNode (Node, TH_EXT );
678+ SDNode *Sbe = BitfieldExtract (N0, Msb, Lsb, DL, VT);
679+ ReplaceNode (Node, Sbe );
668680 return true ;
669681 }
670682
0 commit comments