diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td index f590cf1b171..83f20ad16e9 100644 --- a/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -1283,10 +1283,8 @@ class DPSUB_U_W_DESC : MSA_3R_4R_DESC_BASE<"dpsub_u.w", int_mips_dpsub_u_w, class DPSUB_U_D_DESC : MSA_3R_4R_DESC_BASE<"dpsub_u.d", int_mips_dpsub_u_d, MSA128D, MSA128W, MSA128W>; -class FADD_W_DESC : MSA_3RF_DESC_BASE<"fadd.w", int_mips_fadd_w, MSA128W>, - IsCommutable; -class FADD_D_DESC : MSA_3RF_DESC_BASE<"fadd.d", int_mips_fadd_d, MSA128D>, - IsCommutable; +class FADD_W_DESC : MSA_3RF_DESC_BASE<"fadd.w", fadd, MSA128W>, IsCommutable; +class FADD_D_DESC : MSA_3RF_DESC_BASE<"fadd.d", fadd, MSA128D>, IsCommutable; class FCAF_W_DESC : MSA_3RF_DESC_BASE<"fcaf.w", int_mips_fcaf_w, MSA128W>, IsCommutable; @@ -1344,8 +1342,8 @@ class FCUNE_W_DESC : MSA_3RF_DESC_BASE<"fcune.w", int_mips_fcune_w, MSA128W>, class FCUNE_D_DESC : MSA_3RF_DESC_BASE<"fcune.d", int_mips_fcune_d, MSA128D>, IsCommutable; -class FDIV_W_DESC : MSA_3RF_DESC_BASE<"fdiv.w", int_mips_fdiv_w, MSA128W>; -class FDIV_D_DESC : MSA_3RF_DESC_BASE<"fdiv.d", int_mips_fdiv_d, MSA128D>; +class FDIV_W_DESC : MSA_3RF_DESC_BASE<"fdiv.w", fdiv, MSA128W>; +class FDIV_D_DESC : MSA_3RF_DESC_BASE<"fdiv.d", fdiv, MSA128D>; class FEXDO_H_DESC : MSA_3RF_DESC_BASE<"fexdo.h", int_mips_fexdo_h, MSA128H, MSA128W, MSA128W>; @@ -1392,8 +1390,8 @@ class FILL_H_DESC : MSA_2R_DESC_BASE<"fill.h", int_mips_fill_h, class FILL_W_DESC : MSA_2R_DESC_BASE<"fill.w", int_mips_fill_w, MSA128W, GPR32>; -class FLOG2_W_DESC : MSA_2RF_DESC_BASE<"flog2.w", int_mips_flog2_w, MSA128W>; -class FLOG2_D_DESC : MSA_2RF_DESC_BASE<"flog2.d", int_mips_flog2_d, MSA128D>; +class FLOG2_W_DESC : MSA_2RF_DESC_BASE<"flog2.w", flog2, MSA128W>; +class FLOG2_D_DESC : MSA_2RF_DESC_BASE<"flog2.d", flog2, MSA128D>; class FMADD_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmadd.w", int_mips_fmadd_w, MSA128W>; @@ -1421,11 +1419,11 @@ class FMSUB_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.w", int_mips_fmsub_w, class FMSUB_D_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.d", int_mips_fmsub_d, MSA128D>; -class FMUL_W_DESC : MSA_3RF_DESC_BASE<"fmul.w", int_mips_fmul_w, MSA128W>; -class FMUL_D_DESC : MSA_3RF_DESC_BASE<"fmul.d", int_mips_fmul_d, MSA128D>; +class FMUL_W_DESC : MSA_3RF_DESC_BASE<"fmul.w", fmul, MSA128W>; +class FMUL_D_DESC : MSA_3RF_DESC_BASE<"fmul.d", fmul, MSA128D>; -class FRINT_W_DESC : MSA_2RF_DESC_BASE<"frint.w", int_mips_frint_w, MSA128W>; -class FRINT_D_DESC : MSA_2RF_DESC_BASE<"frint.d", int_mips_frint_d, MSA128D>; +class FRINT_W_DESC : MSA_2RF_DESC_BASE<"frint.w", frint, MSA128W>; +class FRINT_D_DESC : MSA_2RF_DESC_BASE<"frint.d", frint, MSA128D>; class FRCP_W_DESC : MSA_2RF_DESC_BASE<"frcp.w", int_mips_frcp_w, MSA128W>; class FRCP_D_DESC : MSA_2RF_DESC_BASE<"frcp.d", int_mips_frcp_d, MSA128D>; @@ -1453,11 +1451,11 @@ class FSNE_D_DESC : MSA_3RF_DESC_BASE<"fsne.d", int_mips_fsne_d, MSA128D>; class FSOR_W_DESC : MSA_3RF_DESC_BASE<"fsor.w", int_mips_fsor_w, MSA128W>; class FSOR_D_DESC : MSA_3RF_DESC_BASE<"fsor.d", int_mips_fsor_d, MSA128D>; -class FSQRT_W_DESC : MSA_2RF_DESC_BASE<"fsqrt.w", int_mips_fsqrt_w, MSA128W>; -class FSQRT_D_DESC : MSA_2RF_DESC_BASE<"fsqrt.d", int_mips_fsqrt_d, MSA128D>; +class FSQRT_W_DESC : MSA_2RF_DESC_BASE<"fsqrt.w", fsqrt, MSA128W>; +class FSQRT_D_DESC : MSA_2RF_DESC_BASE<"fsqrt.d", fsqrt, MSA128D>; -class FSUB_W_DESC : MSA_3RF_DESC_BASE<"fsub.w", int_mips_fsub_w, MSA128W>; -class FSUB_D_DESC : MSA_3RF_DESC_BASE<"fsub.d", int_mips_fsub_d, MSA128D>; +class FSUB_W_DESC : MSA_3RF_DESC_BASE<"fsub.w", fsub, MSA128W>; +class FSUB_D_DESC : MSA_3RF_DESC_BASE<"fsub.d", fsub, MSA128D>; class FSUEQ_W_DESC : MSA_3RF_DESC_BASE<"fsueq.w", int_mips_fsueq_w, MSA128W>; class FSUEQ_D_DESC : MSA_3RF_DESC_BASE<"fsueq.d", int_mips_fsueq_d, MSA128D>; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 2de21eaffbe..c307aa76d81 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -175,6 +175,16 @@ addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { setOperationAction(ISD::LOAD, Ty, Legal); setOperationAction(ISD::STORE, Ty, Legal); setOperationAction(ISD::BITCAST, Ty, Legal); + + if (Ty != MVT::v8f16) { + setOperationAction(ISD::FADD, Ty, Legal); + setOperationAction(ISD::FDIV, Ty, Legal); + setOperationAction(ISD::FLOG2, Ty, Legal); + setOperationAction(ISD::FMUL, Ty, Legal); + setOperationAction(ISD::FRINT, Ty, Legal); + setOperationAction(ISD::FSQRT, Ty, Legal); + setOperationAction(ISD::FSUB, Ty, Legal); + } } bool @@ -823,6 +833,16 @@ static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { return Result; } +static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { + SDLoc DL(Op); + SDValue Value = Op->getOperand(1); + EVT ResTy = Op->getValueType(0); + + SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); + + return Result; +} + SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { switch (cast(Op->getOperand(0))->getZExtValue()) { @@ -889,6 +909,27 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::mips_div_u_w: case Intrinsic::mips_div_u_d: return lowerMSABinaryIntr(Op, DAG, ISD::UDIV); + case Intrinsic::mips_fadd_w: + case Intrinsic::mips_fadd_d: + return lowerMSABinaryIntr(Op, DAG, ISD::FADD); + case Intrinsic::mips_fdiv_w: + case Intrinsic::mips_fdiv_d: + return lowerMSABinaryIntr(Op, DAG, ISD::FDIV); + case Intrinsic::mips_flog2_w: + case Intrinsic::mips_flog2_d: + return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2); + case Intrinsic::mips_fmul_w: + case Intrinsic::mips_fmul_d: + return lowerMSABinaryIntr(Op, DAG, ISD::FMUL); + case Intrinsic::mips_frint_w: + case Intrinsic::mips_frint_d: + return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT); + case Intrinsic::mips_fsqrt_w: + case Intrinsic::mips_fsqrt_d: + return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT); + case Intrinsic::mips_fsub_w: + case Intrinsic::mips_fsub_d: + return lowerMSABinaryIntr(Op, DAG, ISD::FSUB); } } diff --git a/test/CodeGen/Mips/msa/2rf.ll b/test/CodeGen/Mips/msa/2rf.ll index 74372871ae1..7878b4aaebb 100644 --- a/test/CodeGen/Mips/msa/2rf.ll +++ b/test/CodeGen/Mips/msa/2rf.ll @@ -39,6 +39,38 @@ declare <2 x double> @llvm.mips.flog2.d(<2 x double>) nounwind ; CHECK: flog2.d ; CHECK: st.d ; CHECK: .size llvm_mips_flog2_d_test + +define void @flog2_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_flog2_w_ARG1 + %1 = tail call <4 x float> @llvm.log2.v4f32(<4 x float> %0) + store <4 x float> %1, <4 x float>* @llvm_mips_flog2_w_RES + ret void +} + +declare <4 x float> @llvm.log2.v4f32(<4 x float> %val) + +; CHECK: flog2_w_test: +; CHECK: ld.w +; CHECK: flog2.w +; CHECK: st.w +; CHECK: .size flog2_w_test + +define void @flog2_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_flog2_d_ARG1 + %1 = tail call <2 x double> @llvm.log2.v2f64(<2 x double> %0) + store <2 x double> %1, <2 x double>* @llvm_mips_flog2_d_RES + ret void +} + +declare <2 x double> @llvm.log2.v2f64(<2 x double> %val) + +; CHECK: flog2_d_test: +; CHECK: ld.d +; CHECK: flog2.d +; CHECK: st.d +; CHECK: .size flog2_d_test ; @llvm_mips_frint_w_ARG1 = global <4 x float> , align 16 @llvm_mips_frint_w_RES = global <4 x float> , align 16 @@ -77,6 +109,38 @@ declare <2 x double> @llvm.mips.frint.d(<2 x double>) nounwind ; CHECK: frint.d ; CHECK: st.d ; CHECK: .size llvm_mips_frint_d_test + +define void @frint_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_frint_w_ARG1 + %1 = tail call <4 x float> @llvm.rint.v4f32(<4 x float> %0) + store <4 x float> %1, <4 x float>* @llvm_mips_frint_w_RES + ret void +} + +declare <4 x float> @llvm.rint.v4f32(<4 x float>) nounwind + +; CHECK: frint_w_test: +; CHECK: ld.w +; CHECK: frint.w +; CHECK: st.w +; CHECK: .size frint_w_test + +define void @frint_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_frint_d_ARG1 + %1 = tail call <2 x double> @llvm.rint.v2f64(<2 x double> %0) + store <2 x double> %1, <2 x double>* @llvm_mips_frint_d_RES + ret void +} + +declare <2 x double> @llvm.rint.v2f64(<2 x double>) nounwind + +; CHECK: frint_d_test: +; CHECK: ld.d +; CHECK: frint.d +; CHECK: st.d +; CHECK: .size frint_d_test ; @llvm_mips_frcp_w_ARG1 = global <4 x float> , align 16 @llvm_mips_frcp_w_RES = global <4 x float> , align 16 @@ -191,4 +255,36 @@ declare <2 x double> @llvm.mips.fsqrt.d(<2 x double>) nounwind ; CHECK: fsqrt.d ; CHECK: st.d ; CHECK: .size llvm_mips_fsqrt_d_test + +define void @fsqrt_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_fsqrt_w_ARG1 + %1 = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %0) + store <4 x float> %1, <4 x float>* @llvm_mips_fsqrt_w_RES + ret void +} + +declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) nounwind + +; CHECK: fsqrt_w_test: +; CHECK: ld.w +; CHECK: fsqrt.w +; CHECK: st.w +; CHECK: .size fsqrt_w_test + +define void @fsqrt_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_fsqrt_d_ARG1 + %1 = tail call <2 x double> @llvm.sqrt.v2f64(<2 x double> %0) + store <2 x double> %1, <2 x double>* @llvm_mips_fsqrt_d_RES + ret void +} + +declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) nounwind + +; CHECK: fsqrt_d_test: +; CHECK: ld.d +; CHECK: fsqrt.d +; CHECK: st.d +; CHECK: .size fsqrt_d_test ; diff --git a/test/CodeGen/Mips/msa/3rf.ll b/test/CodeGen/Mips/msa/3rf.ll index 265c8fb4b07..4202dc4cfa8 100644 --- a/test/CodeGen/Mips/msa/3rf.ll +++ b/test/CodeGen/Mips/msa/3rf.ll @@ -45,6 +45,38 @@ declare <2 x double> @llvm.mips.fadd.d(<2 x double>, <2 x double>) nounwind ; CHECK: fadd.d ; CHECK: st.d ; CHECK: .size llvm_mips_fadd_d_test + +define void @fadd_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_fadd_w_ARG1 + %1 = load <4 x float>* @llvm_mips_fadd_w_ARG2 + %2 = fadd <4 x float> %0, %1 + store <4 x float> %2, <4 x float>* @llvm_mips_fadd_w_RES + ret void +} + +; CHECK: fadd_w_test: +; CHECK: ld.w +; CHECK: ld.w +; CHECK: fadd.w +; CHECK: st.w +; CHECK: .size fadd_w_test + +define void @fadd_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_fadd_d_ARG1 + %1 = load <2 x double>* @llvm_mips_fadd_d_ARG2 + %2 = fadd <2 x double> %0, %1 + store <2 x double> %2, <2 x double>* @llvm_mips_fadd_d_RES + ret void +} + +; CHECK: fadd_d_test: +; CHECK: ld.d +; CHECK: ld.d +; CHECK: fadd.d +; CHECK: st.d +; CHECK: .size fadd_d_test ; @llvm_mips_fdiv_w_ARG1 = global <4 x float> , align 16 @llvm_mips_fdiv_w_ARG2 = global <4 x float> , align 16 @@ -89,6 +121,38 @@ declare <2 x double> @llvm.mips.fdiv.d(<2 x double>, <2 x double>) nounwind ; CHECK: fdiv.d ; CHECK: st.d ; CHECK: .size llvm_mips_fdiv_d_test + +define void @fdiv_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_fdiv_w_ARG1 + %1 = load <4 x float>* @llvm_mips_fdiv_w_ARG2 + %2 = fdiv <4 x float> %0, %1 + store <4 x float> %2, <4 x float>* @llvm_mips_fdiv_w_RES + ret void +} + +; CHECK: fdiv_w_test: +; CHECK: ld.w +; CHECK: ld.w +; CHECK: fdiv.w +; CHECK: st.w +; CHECK: .size fdiv_w_test + +define void @fdiv_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_fdiv_d_ARG1 + %1 = load <2 x double>* @llvm_mips_fdiv_d_ARG2 + %2 = fdiv <2 x double> %0, %1 + store <2 x double> %2, <2 x double>* @llvm_mips_fdiv_d_RES + ret void +} + +; CHECK: fdiv_d_test: +; CHECK: ld.d +; CHECK: ld.d +; CHECK: fdiv.d +; CHECK: st.d +; CHECK: .size fdiv_d_test ; @llvm_mips_fmin_w_ARG1 = global <4 x float> , align 16 @llvm_mips_fmin_w_ARG2 = global <4 x float> , align 16 @@ -309,6 +373,38 @@ declare <2 x double> @llvm.mips.fmul.d(<2 x double>, <2 x double>) nounwind ; CHECK: fmul.d ; CHECK: st.d ; CHECK: .size llvm_mips_fmul_d_test + +define void @fmul_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_fmul_w_ARG1 + %1 = load <4 x float>* @llvm_mips_fmul_w_ARG2 + %2 = fmul <4 x float> %0, %1 + store <4 x float> %2, <4 x float>* @llvm_mips_fmul_w_RES + ret void +} + +; CHECK: fmul_w_test: +; CHECK: ld.w +; CHECK: ld.w +; CHECK: fmul.w +; CHECK: st.w +; CHECK: .size fmul_w_test + +define void @fmul_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_fmul_d_ARG1 + %1 = load <2 x double>* @llvm_mips_fmul_d_ARG2 + %2 = fmul <2 x double> %0, %1 + store <2 x double> %2, <2 x double>* @llvm_mips_fmul_d_RES + ret void +} + +; CHECK: fmul_d_test: +; CHECK: ld.d +; CHECK: ld.d +; CHECK: fmul.d +; CHECK: st.d +; CHECK: .size fmul_d_test ; @llvm_mips_fsub_w_ARG1 = global <4 x float> , align 16 @llvm_mips_fsub_w_ARG2 = global <4 x float> , align 16 @@ -354,3 +450,35 @@ declare <2 x double> @llvm.mips.fsub.d(<2 x double>, <2 x double>) nounwind ; CHECK: st.d ; CHECK: .size llvm_mips_fsub_d_test ; + +define void @fsub_w_test() nounwind { +entry: + %0 = load <4 x float>* @llvm_mips_fsub_w_ARG1 + %1 = load <4 x float>* @llvm_mips_fsub_w_ARG2 + %2 = fsub <4 x float> %0, %1 + store <4 x float> %2, <4 x float>* @llvm_mips_fsub_w_RES + ret void +} + +; CHECK: fsub_w_test: +; CHECK: ld.w +; CHECK: ld.w +; CHECK: fsub.w +; CHECK: st.w +; CHECK: .size fsub_w_test + +define void @fsub_d_test() nounwind { +entry: + %0 = load <2 x double>* @llvm_mips_fsub_d_ARG1 + %1 = load <2 x double>* @llvm_mips_fsub_d_ARG2 + %2 = fsub <2 x double> %0, %1 + store <2 x double> %2, <2 x double>* @llvm_mips_fsub_d_RES + ret void +} + +; CHECK: fsub_d_test: +; CHECK: ld.d +; CHECK: ld.d +; CHECK: fsub.d +; CHECK: st.d +; CHECK: .size fsub_d_test