@@ -209,7 +209,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
209209 case ISD::VP_XOR:
210210 case ISD::VP_ADD:
211211 case ISD::VP_SUB:
212- case ISD::VP_MUL: Res = PromoteIntRes_SimpleIntBinOp (N); break ;
212+ case ISD::VP_MUL:
213+ case ISD::CLMUL: Res = PromoteIntRes_SimpleIntBinOp (N); break ;
213214
214215 case ISD::ABDS:
215216 case ISD::AVGCEILS:
@@ -3140,6 +3141,10 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
31403141 ExpandIntRes_FunnelShift (N, Lo, Hi);
31413142 break ;
31423143
3144+ case ISD::CLMUL:
3145+ ExpandIntRes_CLMUL (N, Lo, Hi);
3146+ break ;
3147+
31433148 case ISD::VSCALE:
31443149 ExpandIntRes_VSCALE (N, Lo, Hi);
31453150 break ;
@@ -5476,6 +5481,35 @@ void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N, SDValue &Lo,
54765481 Hi = DAG.getNode (Opc, DL, HalfVT, Select3, Select2, NewShAmt);
54775482}
54785483
5484+ void DAGTypeLegalizer::ExpandIntRes_CLMUL (SDNode *N, SDValue &Lo,
5485+ SDValue &Hi) {
5486+ // Values numbered from least significant to most significant.
5487+ SDValue In1, In2, In3, In4;
5488+ GetExpandedInteger (N->getOperand (0 ), In3, In4);
5489+ GetExpandedInteger (N->getOperand (1 ), In1, In2);
5490+ EVT HalfVT = In1.getValueType ();
5491+ SDLoc DL (N);
5492+
5493+ // CLMUL is carryless so Lo is computed from the low half
5494+ Lo = DAG.getNode (ISD::CLMUL, DL, HalfVT, In1, In3);
5495+ // the high bits not included in CLMUL(A,B) can be computed by
5496+ // BITREVERSE(CLMUL(BITREVERSE(A), BITREVERSE(B))) >> 1
5497+ // Therefore we can compute the 2 hi/lo cross products
5498+ // and the the overflow of the low product
5499+ // and xor them together to compute HI
5500+ SDValue BitRevIn1 = DAG.getNode (ISD::BITREVERSE, DL, HalfVT, In1);
5501+ SDValue BitRevIn3 = DAG.getNode (ISD::BITREVERSE, DL, HalfVT, In3);
5502+ SDValue BitRevLoHi = DAG.getNode (ISD::CLMUL, DL, HalfVT, BitRevIn1, BitRevIn3);
5503+ SDValue LoHi = DAG.getNode (ISD::BITREVERSE, DL, HalfVT, BitRevLoHi);
5504+ SDValue One = DAG.getConstant (0 , DL, HalfVT);
5505+ Hi = DAG.getNode (ISD::SRL, DL, HalfVT, LoHi, One);
5506+
5507+ SDValue HITMP = DAG.getNode (ISD::CLMUL, DL, HalfVT, In1, In4);
5508+ Hi = DAG.getNode (ISD::XOR, DL, HalfVT, Hi, HITMP);
5509+ HITMP = DAG.getNode (ISD::CLMUL, DL, HalfVT, In2, In3);
5510+ Hi = DAG.getNode (ISD::XOR, DL, HalfVT, Hi, HITMP);
5511+ }
5512+
54795513void DAGTypeLegalizer::ExpandIntRes_VSCALE (SDNode *N, SDValue &Lo,
54805514 SDValue &Hi) {
54815515 EVT VT = N->getValueType (0 );
0 commit comments