@@ -10857,6 +10857,64 @@ SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
1085710857 return DAG.getSelect (dl, VT, Cond, SatVal, Result);
1085810858}
1085910859
10860+ void TargetLowering::forceExpandMultiply (SelectionDAG &DAG, const SDLoc &dl,
10861+ bool Signed, SDValue &Lo, SDValue &Hi,
10862+ SDValue LHS, SDValue RHS,
10863+ SDValue HiLHS, SDValue HiRHS) const {
10864+ EVT VT = LHS.getValueType ();
10865+ assert (RHS.getValueType () == VT && " Mismatching operand types" );
10866+
10867+ assert ((HiLHS && HiRHS) || (!HiLHS && !HiRHS));
10868+ assert ((!Signed || !HiLHS) &&
10869+ " Signed flag should only be set when HiLHS and RiRHS are null" );
10870+
10871+ // We'll expand the multiplication by brute force because we have no other
10872+ // options. This is a trivially-generalized version of the code from
10873+ // Hacker's Delight (itself derived from Knuth's Algorithm M from section
10874+ // 4.3.1). If Signed is set, we can use arithmetic right shifts to propagate
10875+ // sign bits while calculating the Hi half.
10876+ unsigned Bits = VT.getSizeInBits ();
10877+ unsigned HalfBits = Bits / 2 ;
10878+ SDValue Mask = DAG.getConstant (APInt::getLowBitsSet (Bits, HalfBits), dl, VT);
10879+ SDValue LL = DAG.getNode (ISD::AND, dl, VT, LHS, Mask);
10880+ SDValue RL = DAG.getNode (ISD::AND, dl, VT, RHS, Mask);
10881+
10882+ SDValue T = DAG.getNode (ISD::MUL, dl, VT, LL, RL);
10883+ SDValue TL = DAG.getNode (ISD::AND, dl, VT, T, Mask);
10884+
10885+ SDValue Shift = DAG.getShiftAmountConstant (HalfBits, VT, dl);
10886+ // This is always an unsigned shift.
10887+ SDValue TH = DAG.getNode (ISD::SRL, dl, VT, T, Shift);
10888+
10889+ unsigned ShiftOpc = Signed ? ISD::SRA : ISD::SRL;
10890+ SDValue LH = DAG.getNode (ShiftOpc, dl, VT, LHS, Shift);
10891+ SDValue RH = DAG.getNode (ShiftOpc, dl, VT, RHS, Shift);
10892+
10893+ SDValue U =
10894+ DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RL), TH);
10895+ SDValue UL = DAG.getNode (ISD::AND, dl, VT, U, Mask);
10896+ SDValue UH = DAG.getNode (ShiftOpc, dl, VT, U, Shift);
10897+
10898+ SDValue V =
10899+ DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LL, RH), UL);
10900+ SDValue VH = DAG.getNode (ShiftOpc, dl, VT, V, Shift);
10901+
10902+ Lo = DAG.getNode (ISD::ADD, dl, VT, TL,
10903+ DAG.getNode (ISD::SHL, dl, VT, V, Shift));
10904+
10905+ Hi = DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RH),
10906+ DAG.getNode (ISD::ADD, dl, VT, UH, VH));
10907+
10908+ // If HiLHS and HiRHS are set, multiply them by the opposite low part and add
10909+ // the products to Hi.
10910+ if (HiLHS) {
10911+ Hi = DAG.getNode (ISD::ADD, dl, VT, Hi,
10912+ DAG.getNode (ISD::ADD, dl, VT,
10913+ DAG.getNode (ISD::MUL, dl, VT, HiRHS, LHS),
10914+ DAG.getNode (ISD::MUL, dl, VT, RHS, HiLHS)));
10915+ }
10916+ }
10917+
1086010918void TargetLowering::forceExpandWideMUL (SelectionDAG &DAG, const SDLoc &dl,
1086110919 bool Signed, EVT WideVT,
1086210920 const SDValue LL, const SDValue LH,
@@ -10877,45 +10935,7 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
1087710935 LC = RTLIB::MUL_I128;
1087810936
1087910937 if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName (LC)) {
10880- // We'll expand the multiplication by brute force because we have no other
10881- // options. This is a trivially-generalized version of the code from
10882- // Hacker's Delight (itself derived from Knuth's Algorithm M from section
10883- // 4.3.1).
10884- EVT VT = LL.getValueType ();
10885- unsigned Bits = VT.getSizeInBits ();
10886- unsigned HalfBits = Bits >> 1 ;
10887- SDValue Mask =
10888- DAG.getConstant (APInt::getLowBitsSet (Bits, HalfBits), dl, VT);
10889- SDValue LLL = DAG.getNode (ISD::AND, dl, VT, LL, Mask);
10890- SDValue RLL = DAG.getNode (ISD::AND, dl, VT, RL, Mask);
10891-
10892- SDValue T = DAG.getNode (ISD::MUL, dl, VT, LLL, RLL);
10893- SDValue TL = DAG.getNode (ISD::AND, dl, VT, T, Mask);
10894-
10895- SDValue Shift = DAG.getShiftAmountConstant (HalfBits, VT, dl);
10896- SDValue TH = DAG.getNode (ISD::SRL, dl, VT, T, Shift);
10897- SDValue LLH = DAG.getNode (ISD::SRL, dl, VT, LL, Shift);
10898- SDValue RLH = DAG.getNode (ISD::SRL, dl, VT, RL, Shift);
10899-
10900- SDValue U = DAG.getNode (ISD::ADD, dl, VT,
10901- DAG.getNode (ISD::MUL, dl, VT, LLH, RLL), TH);
10902- SDValue UL = DAG.getNode (ISD::AND, dl, VT, U, Mask);
10903- SDValue UH = DAG.getNode (ISD::SRL, dl, VT, U, Shift);
10904-
10905- SDValue V = DAG.getNode (ISD::ADD, dl, VT,
10906- DAG.getNode (ISD::MUL, dl, VT, LLL, RLH), UL);
10907- SDValue VH = DAG.getNode (ISD::SRL, dl, VT, V, Shift);
10908-
10909- SDValue W =
10910- DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LLH, RLH),
10911- DAG.getNode (ISD::ADD, dl, VT, UH, VH));
10912- Lo = DAG.getNode (ISD::ADD, dl, VT, TL,
10913- DAG.getNode (ISD::SHL, dl, VT, V, Shift));
10914-
10915- Hi = DAG.getNode (ISD::ADD, dl, VT, W,
10916- DAG.getNode (ISD::ADD, dl, VT,
10917- DAG.getNode (ISD::MUL, dl, VT, RH, LL),
10918- DAG.getNode (ISD::MUL, dl, VT, RL, LH)));
10938+ forceExpandMultiply (DAG, dl, /* Signed=*/ false , Lo, Hi, LL, RL, LH, RH);
1091910939 } else {
1092010940 // Attempt a libcall.
1092110941 SDValue Ret;
@@ -10965,58 +10985,50 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
1096510985 else if (WideVT == MVT::i128 )
1096610986 LC = RTLIB::MUL_I128;
1096710987
10968- if (LC != RTLIB::UNKNOWN_LIBCALL && getLibcallName (LC)) {
10969- SDValue HiLHS, HiRHS;
10970- if (Signed) {
10971- // The high part is obtained by SRA'ing all but one of the bits of low
10972- // part.
10973- unsigned LoSize = VT.getFixedSizeInBits ();
10974- SDValue Shift = DAG.getShiftAmountConstant (LoSize - 1 , VT, dl);
10975- HiLHS = DAG.getNode (ISD::SRA, dl, VT, LHS, Shift);
10976- HiRHS = DAG.getNode (ISD::SRA, dl, VT, RHS, Shift);
10977- } else {
10978- HiLHS = DAG.getConstant (0 , dl, VT);
10979- HiRHS = DAG.getConstant (0 , dl, VT);
10980- }
10981- forceExpandWideMUL (DAG, dl, Signed, WideVT, LHS, HiLHS, RHS, HiRHS, Lo, Hi);
10988+ if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName (LC)) {
10989+ forceExpandMultiply (DAG, dl, Signed, Lo, Hi, LHS, RHS);
1098210990 return ;
1098310991 }
1098410992
10985- // Expand the multiplication by brute force. This is a generalized-version of
10986- // the code from Hacker's Delight (itself derived from Knuth's Algorithm M
10987- // from section 4.3.1) combined with the Hacker's delight code
10988- // for calculating mulhs.
10989- unsigned Bits = VT.getSizeInBits ();
10990- unsigned HalfBits = Bits / 2 ;
10991- SDValue Mask = DAG.getConstant (APInt::getLowBitsSet (Bits, HalfBits), dl, VT);
10992- SDValue LL = DAG.getNode (ISD::AND, dl, VT, LHS, Mask);
10993- SDValue RL = DAG.getNode (ISD::AND, dl, VT, RHS, Mask);
10994-
10995- SDValue T = DAG.getNode (ISD::MUL, dl, VT, LL, RL);
10996- SDValue TL = DAG.getNode (ISD::AND, dl, VT, T, Mask);
10997-
10998- SDValue Shift = DAG.getShiftAmountConstant (HalfBits, VT, dl);
10999- // This is always an unsigned shift.
11000- SDValue TH = DAG.getNode (ISD::SRL, dl, VT, T, Shift);
11001-
11002- unsigned ShiftOpc = Signed ? ISD::SRA : ISD::SRL;
11003- SDValue LH = DAG.getNode (ShiftOpc, dl, VT, LHS, Shift);
11004- SDValue RH = DAG.getNode (ShiftOpc, dl, VT, RHS, Shift);
11005-
11006- SDValue U =
11007- DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RL), TH);
11008- SDValue UL = DAG.getNode (ISD::AND, dl, VT, U, Mask);
11009- SDValue UH = DAG.getNode (ShiftOpc, dl, VT, U, Shift);
11010-
11011- SDValue V =
11012- DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LL, RH), UL);
11013- SDValue VH = DAG.getNode (ShiftOpc, dl, VT, V, Shift);
11014-
11015- Lo = DAG.getNode (ISD::ADD, dl, VT, TL,
11016- DAG.getNode (ISD::SHL, dl, VT, V, Shift));
10993+ SDValue HiLHS, HiRHS;
10994+ if (Signed) {
10995+ // The high part is obtained by SRA'ing all but one of the bits of low
10996+ // part.
10997+ unsigned LoSize = VT.getFixedSizeInBits ();
10998+ SDValue Shift = DAG.getShiftAmountConstant (LoSize - 1 , VT, dl);
10999+ HiLHS = DAG.getNode (ISD::SRA, dl, VT, LHS, Shift);
11000+ HiRHS = DAG.getNode (ISD::SRA, dl, VT, RHS, Shift);
11001+ } else {
11002+ HiLHS = DAG.getConstant (0 , dl, VT);
11003+ HiRHS = DAG.getConstant (0 , dl, VT);
11004+ }
1101711005
11018- Hi = DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RH),
11019- DAG.getNode (ISD::ADD, dl, VT, UH, VH));
11006+ // Attempt a libcall.
11007+ SDValue Ret;
11008+ TargetLowering::MakeLibCallOptions CallOptions;
11009+ CallOptions.setIsSigned (Signed);
11010+ CallOptions.setIsPostTypeLegalization (true );
11011+ if (shouldSplitFunctionArgumentsAsLittleEndian (DAG.getDataLayout ())) {
11012+ // Halves of WideVT are packed into registers in different order
11013+ // depending on platform endianness. This is usually handled by
11014+ // the C calling convention, but we can't defer to it in
11015+ // the legalizer.
11016+ SDValue Args[] = {LHS, HiLHS, RHS, HiRHS};
11017+ Ret = makeLibCall (DAG, LC, WideVT, Args, CallOptions, dl).first ;
11018+ } else {
11019+ SDValue Args[] = {HiLHS, LHS, HiRHS, RHS};
11020+ Ret = makeLibCall (DAG, LC, WideVT, Args, CallOptions, dl).first ;
11021+ }
11022+ assert (Ret.getOpcode () == ISD::MERGE_VALUES &&
11023+ " Ret value is a collection of constituent nodes holding result." );
11024+ if (DAG.getDataLayout ().isLittleEndian ()) {
11025+ // Same as above.
11026+ Lo = Ret.getOperand (0 );
11027+ Hi = Ret.getOperand (1 );
11028+ } else {
11029+ Lo = Ret.getOperand (1 );
11030+ Hi = Ret.getOperand (0 );
11031+ }
1102011032}
1102111033
1102211034SDValue
0 commit comments