@@ -1642,6 +1642,12 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
16421642
16431643 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
16441644
1645+ if (Subtarget->hasSVE()) {
1646+ setOperationAction(ISD::FLDEXP, MVT::f64, Custom);
1647+ setOperationAction(ISD::FLDEXP, MVT::f32, Custom);
1648+ setOperationAction(ISD::FLDEXP, MVT::f16, Custom);
1649+ }
1650+
16451651 PredictableSelectIsExpensive = Subtarget->predictableSelectIsExpensive();
16461652
16471653 IsStrictFPEnabled = true;
@@ -5895,6 +5901,49 @@ static SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) {
58955901 return SDValue();
58965902}
58975903
5904+ static SDValue LowerFLDEXP(SDValue Op, SelectionDAG &DAG) {
5905+ SDValue X = Op.getOperand(0);
5906+ EVT XScalarTy = X.getValueType();
5907+ SDValue Exp = Op.getOperand(1);
5908+
5909+ SDLoc DL(Op);
5910+ EVT XVT, ExpVT;
5911+ switch (Op.getSimpleValueType().SimpleTy) {
5912+ default:
5913+ return SDValue();
5914+ case MVT::f16:
5915+ X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X);
5916+ [[fallthrough]];
5917+ case MVT::f32:
5918+ XVT = MVT::nxv4f32;
5919+ ExpVT = MVT::nxv4i32;
5920+ break;
5921+ case MVT::f64:
5922+ XVT = MVT::nxv2f64;
5923+ ExpVT = MVT::nxv2i64;
5924+ Exp = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Exp);
5925+ break;
5926+ }
5927+
5928+ SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
5929+ SDValue VX =
5930+ DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, XVT, DAG.getUNDEF(XVT), X, Zero);
5931+ SDValue VExp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ExpVT,
5932+ DAG.getUNDEF(ExpVT), Exp, Zero);
5933+ SDValue VPg = getPTrue(DAG, DL, XVT.changeVectorElementType(MVT::i1),
5934+ AArch64SVEPredPattern::all);
5935+ SDValue FScale =
5936+ DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, XVT,
5937+ DAG.getConstant(Intrinsic::aarch64_sve_fscale, DL, MVT::i64),
5938+ VPg, VX, VExp);
5939+ SDValue Final =
5940+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, X.getValueType(), FScale, Zero);
5941+ if (X.getValueType() != XScalarTy)
5942+ Final = DAG.getNode(ISD::FP_ROUND, DL, XScalarTy, Final,
5943+ DAG.getIntPtrConstant(1, SDLoc(Op)));
5944+ return Final;
5945+ }
5946+
58985947SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
58995948 SelectionDAG &DAG) const {
59005949 LLVM_DEBUG(dbgs() << "Custom lowering: ");
@@ -6215,6 +6264,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
62156264 case ISD::FSHL:
62166265 case ISD::FSHR:
62176266 return LowerFunnelShift(Op, DAG);
6267+ case ISD::FLDEXP:
6268+ return LowerFLDEXP(Op, DAG);
62186269 }
62196270}
62206271
0 commit comments