@@ -10857,6 +10857,64 @@ SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
10857
10857
return DAG.getSelect (dl, VT, Cond, SatVal, Result);
10858
10858
}
10859
10859
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
+
10860
10918
void TargetLowering::forceExpandWideMUL (SelectionDAG &DAG, const SDLoc &dl,
10861
10919
bool Signed, EVT WideVT,
10862
10920
const SDValue LL, const SDValue LH,
@@ -10877,45 +10935,7 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
10877
10935
LC = RTLIB::MUL_I128;
10878
10936
10879
10937
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);
10919
10939
} else {
10920
10940
// Attempt a libcall.
10921
10941
SDValue Ret;
@@ -10965,58 +10985,50 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
10965
10985
else if (WideVT == MVT::i128 )
10966
10986
LC = RTLIB::MUL_I128;
10967
10987
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);
10982
10990
return ;
10983
10991
}
10984
10992
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
+ }
11017
11005
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
+ }
11020
11032
}
11021
11033
11022
11034
SDValue
0 commit comments