@@ -904,6 +904,98 @@ void HexagonDAGToDAGISel::SelectQ2V(SDNode *N) {
904
904
ReplaceNode (N, T);
905
905
}
906
906
907
+ void HexagonDAGToDAGISel::FDiv (SDNode *N) {
908
+ const SDLoc &dl (N);
909
+ ArrayRef<EVT> ResultType (N->value_begin (), N->value_end ());
910
+ SmallVector<SDValue, 2 > Ops;
911
+ Ops = {N->getOperand (0 ), N->getOperand (1 )};
912
+ SDVTList VTs;
913
+ VTs = CurDAG->getVTList (MVT::f32 , MVT::f32 );
914
+ SDNode *ResScale = CurDAG->getMachineNode (Hexagon::F2_sfrecipa, dl, VTs, Ops);
915
+ SDNode *D = CurDAG->getMachineNode (Hexagon::F2_sffixupd, dl, MVT::f32 , Ops);
916
+
917
+ SDValue C = CurDAG->getTargetConstant (0x3f800000 , dl, MVT::i32 );
918
+ SDNode *constNode =
919
+ CurDAG->getMachineNode (Hexagon::A2_tfrsi, dl, MVT::f32 , C);
920
+
921
+ SDNode *n = CurDAG->getMachineNode (Hexagon::F2_sffixupn, dl, MVT::f32 , Ops);
922
+ SDNode *Err = CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 ,
923
+ SDValue (constNode, 0 ), SDValue (D, 0 ),
924
+ SDValue (ResScale, 0 ));
925
+ SDNode *NewRec = CurDAG->getMachineNode (Hexagon::F2_sffma_lib, dl, MVT::f32 ,
926
+ SDValue (ResScale, 0 ), SDValue (Err, 0 ),
927
+ SDValue (ResScale, 0 ));
928
+ SDNode *newErr = CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 ,
929
+ SDValue (constNode, 0 ), SDValue (D, 0 ),
930
+ SDValue (NewRec, 0 ));
931
+ SDNode *q = CurDAG->getMachineNode (
932
+ Hexagon::A2_andir, dl, MVT::f32 , SDValue (n, 0 ),
933
+ CurDAG->getTargetConstant (0x80000000 , dl, MVT::i32 ));
934
+ SDNode *NewQ =
935
+ CurDAG->getMachineNode (Hexagon::F2_sffma_lib, dl, MVT::f32 , SDValue (q, 0 ),
936
+ SDValue (n, 0 ), SDValue (NewRec, 0 ));
937
+ SDNode *NNewRec = CurDAG->getMachineNode (
938
+ Hexagon::F2_sffma_lib, dl, MVT::f32 , SDValue (NewRec, 0 ),
939
+ SDValue (newErr, 0 ), SDValue (NewRec, 0 ));
940
+ SDNode *qErr =
941
+ CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 , SDValue (n, 0 ),
942
+ SDValue (D, 0 ), SDValue (NewQ, 0 ));
943
+ SDNode *NNewQ = CurDAG->getMachineNode (Hexagon::F2_sffma_lib, dl, MVT::f32 ,
944
+ SDValue (NewQ, 0 ), SDValue (qErr, 0 ),
945
+ SDValue (NNewRec, 0 ));
946
+
947
+ SDNode *NqErr =
948
+ CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 , SDValue (n, 0 ),
949
+ SDValue (NNewQ, 0 ), SDValue (D, 0 ));
950
+ std::array<SDValue, 4 > temp1 = {SDValue (NNewQ, 0 ), SDValue (NqErr, 0 ),
951
+ SDValue (NNewRec, 0 ), SDValue (ResScale, 1 )};
952
+ ArrayRef<SDValue> OpValue1 (temp1);
953
+ SDNode *FinalNewQ =
954
+ CurDAG->getMachineNode (Hexagon::F2_sffma_sc, dl, MVT::f32 , OpValue1);
955
+ ReplaceNode (N, FinalNewQ);
956
+ }
957
+
958
+ void HexagonDAGToDAGISel::FastFDiv (SDNode *N) {
959
+ const SDLoc &dl (N);
960
+ ArrayRef<EVT> ResultType (N->value_begin (), N->value_end ());
961
+ SmallVector<SDValue, 2 > Ops;
962
+ Ops = {N->getOperand (0 ), N->getOperand (1 )};
963
+ SDVTList VTs;
964
+ VTs = CurDAG->getVTList (MVT::f32 , MVT::f32 );
965
+ SDNode *ResScale = CurDAG->getMachineNode (Hexagon::F2_sfrecipa, dl, VTs, Ops);
966
+ SDNode *D = CurDAG->getMachineNode (Hexagon::F2_sffixupd, dl, MVT::f32 , Ops);
967
+
968
+ SDValue C = CurDAG->getTargetConstant (0x3f800000 , dl, MVT::i32 );
969
+ SDNode *constNode =
970
+ CurDAG->getMachineNode (Hexagon::A2_tfrsi, dl, MVT::f32 , C);
971
+
972
+ SDNode *n = CurDAG->getMachineNode (Hexagon::F2_sffixupn, dl, MVT::f32 , Ops);
973
+ SDNode *Err = CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 ,
974
+ SDValue (constNode, 0 ), SDValue (D, 0 ),
975
+ SDValue (ResScale, 0 ));
976
+ SDNode *NewRec = CurDAG->getMachineNode (Hexagon::F2_sffma_lib, dl, MVT::f32 ,
977
+ SDValue (ResScale, 0 ), SDValue (Err, 0 ),
978
+ SDValue (ResScale, 0 ));
979
+ SDNode *newErr = CurDAG->getMachineNode (Hexagon::F2_sffms_lib, dl, MVT::f32 ,
980
+ SDValue (constNode, 0 ), SDValue (D, 0 ),
981
+ SDValue (NewRec, 0 ));
982
+
983
+ SDNode *NNewRec = CurDAG->getMachineNode (
984
+ Hexagon::F2_sffma_lib, dl, MVT::f32 , SDValue (NewRec, 0 ),
985
+ SDValue (newErr, 0 ), SDValue (NewRec, 0 ));
986
+ SDNode *FinalNewQ = CurDAG->getMachineNode (
987
+ Hexagon::F2_sfmpy, dl, MVT::f32 , SDValue (NNewRec, 0 ), SDValue (n, 0 ));
988
+ ReplaceNode (N, FinalNewQ);
989
+ }
990
+
991
+ void HexagonDAGToDAGISel::SelectFDiv (SDNode *N) {
992
+ if (N->getFlags ().hasAllowReassociation ())
993
+ FastFDiv (N);
994
+ else
995
+ FDiv (N);
996
+ return ;
997
+ }
998
+
907
999
void HexagonDAGToDAGISel::Select (SDNode *N) {
908
1000
if (N->isMachineOpcode ())
909
1001
return N->setNodeId (-1 ); // Already selected.
@@ -949,6 +1041,8 @@ void HexagonDAGToDAGISel::Select(SDNode *N) {
949
1041
case HexagonISD::D2P: return SelectD2P (N);
950
1042
case HexagonISD::Q2V: return SelectQ2V (N);
951
1043
case HexagonISD::V2Q: return SelectV2Q (N);
1044
+ case ISD::FDIV:
1045
+ return SelectFDiv (N);
952
1046
}
953
1047
954
1048
SelectCode (N);
0 commit comments