@@ -446,6 +446,10 @@ HexagonTargetLowering::initializeHVXLowering() {
446446 }
447447 }
448448
449+ // Include cases which are not hander earlier
450+ setOperationAction (ISD::UINT_TO_FP, MVT::v32i1, Custom);
451+ setOperationAction (ISD::UINT_TO_FP, MVT::v64i1, Custom);
452+
449453 setTargetDAGCombine ({ISD::CONCAT_VECTORS, ISD::TRUNCATE, ISD::VSELECT});
450454}
451455
@@ -2333,6 +2337,123 @@ HexagonTargetLowering::LowerHvxFpToInt(SDValue Op, SelectionDAG &DAG) const {
23332337 return ExpandHvxFpToInt (Op, DAG);
23342338}
23352339
2340+ // For vector type v32i1 uint_to_fp to v32f32:
2341+ // R1 = #1, R2 holds the v32i1 param
2342+ // V1 = vsplat(R1)
2343+ // V2 = vsplat(R2)
2344+ // Q0 = vand(V1,R1)
2345+ // V0.w=prefixsum(Q0)
2346+ // V0.w=vsub(V0.w,V1.w)
2347+ // V2.w = vlsr(V2.w,V0.w)
2348+ // V2 = vand(V2,V1)
2349+ // V2.sf = V2.w
2350+ SDValue HexagonTargetLowering::LowerHvxPred32ToFp (SDValue PredOp,
2351+ SelectionDAG &DAG) const {
2352+
2353+ MVT ResTy = ty (PredOp);
2354+ const SDLoc &dl (PredOp);
2355+
2356+ SDValue Const = DAG.getTargetConstant (0x1 , dl, MVT::i32 );
2357+ SDNode *RegConst = DAG.getMachineNode (Hexagon::A2_tfrsi, dl, MVT::i32 , Const);
2358+ SDNode *SplatConst = DAG.getMachineNode (Hexagon::V6_lvsplatw, dl, MVT::v32i32,
2359+ SDValue (RegConst, 0 ));
2360+ SDNode *PredTransfer =
2361+ DAG.getMachineNode (Hexagon::V6_vandvrt, dl, MVT::v32i1,
2362+ SDValue (SplatConst, 0 ), SDValue (RegConst, 0 ));
2363+ SDNode *PrefixSum = DAG.getMachineNode (Hexagon::V6_vprefixqw, dl, MVT::v32i32,
2364+ SDValue (PredTransfer, 0 ));
2365+ SDNode *SplatParam = DAG.getMachineNode (
2366+ Hexagon::V6_lvsplatw, dl, MVT::v32i32,
2367+ DAG.getNode (ISD::BITCAST, dl, MVT::i32 , PredOp.getOperand (0 )));
2368+ SDNode *Vsub =
2369+ DAG.getMachineNode (Hexagon::V6_vsubw, dl, MVT::v32i32,
2370+ SDValue (PrefixSum, 0 ), SDValue (SplatConst, 0 ));
2371+ SDNode *IndexShift =
2372+ DAG.getMachineNode (Hexagon::V6_vlsrwv, dl, MVT::v32i32,
2373+ SDValue (SplatParam, 0 ), SDValue (Vsub, 0 ));
2374+ SDNode *MaskOff =
2375+ DAG.getMachineNode (Hexagon::V6_vand, dl, MVT::v32i32,
2376+ SDValue (IndexShift, 0 ), SDValue (SplatConst, 0 ));
2377+ SDNode *Convert = DAG.getMachineNode (Hexagon::V6_vconv_sf_w, dl, ResTy,
2378+ SDValue (MaskOff, 0 ));
2379+ return SDValue (Convert, 0 );
2380+ }
2381+
2382+ // For vector type v64i1 uint_to_fo to v64f16:
2383+ // i64 R32 = bitcast v64i1 R3:2 (R3:2 holds v64i1)
2384+ // R3 = subreg_high (R32)
2385+ // R2 = subreg_low (R32)
2386+ // R1 = #1
2387+ // V1 = vsplat(R1)
2388+ // V2 = vsplat(R2)
2389+ // V3 = vsplat(R3)
2390+ // Q0 = vand(V1,R1)
2391+ // V0.w=prefixsum(Q0)
2392+ // V0.w=vsub(V0.w,V1.w)
2393+ // V2.w = vlsr(V2.w,V0.w)
2394+ // V3.w = vlsr(V3.w,V0.w)
2395+ // V2 = vand(V2,V1)
2396+ // V3 = vand(V3,V1)
2397+ // V2.h = vpacke(V3.w,V2.w)
2398+ // V2.hf = V2.h
2399+ SDValue HexagonTargetLowering::LowerHvxPred64ToFp (SDValue PredOp,
2400+ SelectionDAG &DAG) const {
2401+
2402+ MVT ResTy = ty (PredOp);
2403+ const SDLoc &dl (PredOp);
2404+
2405+ SDValue Inp = DAG.getNode (ISD::BITCAST, dl, MVT::i64 , PredOp.getOperand (0 ));
2406+ // Get the hi and lo regs
2407+ SDValue HiReg =
2408+ DAG.getTargetExtractSubreg (Hexagon::isub_hi, dl, MVT::i32 , Inp);
2409+ SDValue LoReg =
2410+ DAG.getTargetExtractSubreg (Hexagon::isub_lo, dl, MVT::i32 , Inp);
2411+ // Get constant #1 and splat into vector V1
2412+ SDValue Const = DAG.getTargetConstant (0x1 , dl, MVT::i32 );
2413+ SDNode *RegConst = DAG.getMachineNode (Hexagon::A2_tfrsi, dl, MVT::i32 , Const);
2414+ SDNode *SplatConst = DAG.getMachineNode (Hexagon::V6_lvsplatw, dl, MVT::v32i32,
2415+ SDValue (RegConst, 0 ));
2416+ // Splat the hi and lo args
2417+ SDNode *SplatHi =
2418+ DAG.getMachineNode (Hexagon::V6_lvsplatw, dl, MVT::v32i32,
2419+ DAG.getNode (ISD::BITCAST, dl, MVT::i32 , HiReg));
2420+ SDNode *SplatLo =
2421+ DAG.getMachineNode (Hexagon::V6_lvsplatw, dl, MVT::v32i32,
2422+ DAG.getNode (ISD::BITCAST, dl, MVT::i32 , LoReg));
2423+ // vand between splatted const and const
2424+ SDNode *PredTransfer =
2425+ DAG.getMachineNode (Hexagon::V6_vandvrt, dl, MVT::v32i1,
2426+ SDValue (SplatConst, 0 ), SDValue (RegConst, 0 ));
2427+ // Get the prefixsum
2428+ SDNode *PrefixSum = DAG.getMachineNode (Hexagon::V6_vprefixqw, dl, MVT::v32i32,
2429+ SDValue (PredTransfer, 0 ));
2430+ // Get the vsub
2431+ SDNode *Vsub =
2432+ DAG.getMachineNode (Hexagon::V6_vsubw, dl, MVT::v32i32,
2433+ SDValue (PrefixSum, 0 ), SDValue (SplatConst, 0 ));
2434+ // Get vlsr for hi and lo
2435+ SDNode *IndexShift_hi =
2436+ DAG.getMachineNode (Hexagon::V6_vlsrwv, dl, MVT::v32i32,
2437+ SDValue (SplatHi, 0 ), SDValue (Vsub, 0 ));
2438+ SDNode *IndexShift_lo =
2439+ DAG.getMachineNode (Hexagon::V6_vlsrwv, dl, MVT::v32i32,
2440+ SDValue (SplatLo, 0 ), SDValue (Vsub, 0 ));
2441+ // Get vand of hi and lo
2442+ SDNode *MaskOff_hi =
2443+ DAG.getMachineNode (Hexagon::V6_vand, dl, MVT::v32i32,
2444+ SDValue (IndexShift_hi, 0 ), SDValue (SplatConst, 0 ));
2445+ SDNode *MaskOff_lo =
2446+ DAG.getMachineNode (Hexagon::V6_vand, dl, MVT::v32i32,
2447+ SDValue (IndexShift_lo, 0 ), SDValue (SplatConst, 0 ));
2448+ // Pack them
2449+ SDNode *Pack =
2450+ DAG.getMachineNode (Hexagon::V6_vpackeh, dl, MVT::v64i16,
2451+ SDValue (MaskOff_hi, 0 ), SDValue (MaskOff_lo, 0 ));
2452+ SDNode *Convert =
2453+ DAG.getMachineNode (Hexagon::V6_vconv_hf_h, dl, ResTy, SDValue (Pack, 0 ));
2454+ return SDValue (Convert, 0 );
2455+ }
2456+
23362457SDValue
23372458HexagonTargetLowering::LowerHvxIntToFp (SDValue Op, SelectionDAG &DAG) const {
23382459 // Catch invalid conversion ops (just in case).
@@ -2343,6 +2464,13 @@ HexagonTargetLowering::LowerHvxIntToFp(SDValue Op, SelectionDAG &DAG) const {
23432464 MVT IntTy = ty (Op.getOperand (0 )).getVectorElementType ();
23442465 MVT FpTy = ResTy.getVectorElementType ();
23452466
2467+ if (Op.getOpcode () == ISD::UINT_TO_FP) {
2468+ if (ResTy == MVT::v32f32 && ty (Op.getOperand (0 )) == MVT::v32i1)
2469+ return LowerHvxPred32ToFp (Op, DAG);
2470+ if (ResTy == MVT::v64f16 && ty (Op.getOperand (0 )) == MVT::v64i1)
2471+ return LowerHvxPred64ToFp (Op, DAG);
2472+ }
2473+
23462474 if (Subtarget.useHVXIEEEFPOps ()) {
23472475 // There are only conversions to f16.
23482476 if (FpTy == MVT::f16 ) {
0 commit comments