@@ -446,6 +446,10 @@ HexagonTargetLowering::initializeHVXLowering() {
446
446
}
447
447
}
448
448
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
+
449
453
setTargetDAGCombine ({ISD::CONCAT_VECTORS, ISD::TRUNCATE, ISD::VSELECT});
450
454
}
451
455
@@ -2333,6 +2337,123 @@ HexagonTargetLowering::LowerHvxFpToInt(SDValue Op, SelectionDAG &DAG) const {
2333
2337
return ExpandHvxFpToInt (Op, DAG);
2334
2338
}
2335
2339
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
+
2336
2457
SDValue
2337
2458
HexagonTargetLowering::LowerHvxIntToFp (SDValue Op, SelectionDAG &DAG) const {
2338
2459
// Catch invalid conversion ops (just in case).
@@ -2343,6 +2464,13 @@ HexagonTargetLowering::LowerHvxIntToFp(SDValue Op, SelectionDAG &DAG) const {
2343
2464
MVT IntTy = ty (Op.getOperand (0 )).getVectorElementType ();
2344
2465
MVT FpTy = ResTy.getVectorElementType ();
2345
2466
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
+
2346
2474
if (Subtarget.useHVXIEEEFPOps ()) {
2347
2475
// There are only conversions to f16.
2348
2476
if (FpTy == MVT::f16 ) {
0 commit comments