[mips][msa] Added support for matching fmsub.[wd] from normal IR (i.e. not intrinsics)

llvm-svn: 192435
This commit is contained in:
Daniel Sanders 2013-10-11 10:27:32 +00:00
parent 4eec834c2b
commit e67bd87c48
3 changed files with 51 additions and 4 deletions

View File

@ -295,6 +295,8 @@ def vsplati64_simm5 : SplatComplexPattern<vsplat_simm5, v2i64, 1,
def vsplat_uimm_pow2 : ComplexPattern<vAny, 1, "selectVSplatUimmPow2",
[build_vector, bitconvert]>;
def fms : PatFrag<(ops node:$wd, node:$ws, node:$wt),
(fsub node:$wd, (fmul node:$ws, node:$wt))>;
// Immediates
def immSExt5 : ImmLeaf<i32, [{return isInt<5>(Imm);}]>;
def immSExt10: ImmLeaf<i32, [{return isInt<10>(Imm);}]>;
@ -1816,10 +1818,8 @@ class FMIN_A_W_DESC : MSA_3RF_DESC_BASE<"fmin_a.w", int_mips_fmin_a_w,
class FMIN_A_D_DESC : MSA_3RF_DESC_BASE<"fmin_a.d", int_mips_fmin_a_d,
MSA128DOpnd>;
class FMSUB_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.w", int_mips_fmsub_w,
MSA128WOpnd>;
class FMSUB_D_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.d", int_mips_fmsub_d,
MSA128DOpnd>;
class FMSUB_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.w", fms, MSA128WOpnd>;
class FMSUB_D_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.d", fms, MSA128DOpnd>;
class FMUL_W_DESC : MSA_3RF_DESC_BASE<"fmul.w", fmul, MSA128WOpnd>;
class FMUL_D_DESC : MSA_3RF_DESC_BASE<"fmul.d", fmul, MSA128DOpnd>;

View File

@ -1341,6 +1341,13 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::mips_fmul_d:
return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
case Intrinsic::mips_fmsub_w:
case Intrinsic::mips_fmsub_d: {
EVT ResTy = Op->getValueType(0);
return DAG.getNode(ISD::FSUB, SDLoc(Op), ResTy, Op->getOperand(1),
DAG.getNode(ISD::FMUL, SDLoc(Op), ResTy,
Op->getOperand(2), Op->getOperand(3)));
}
case Intrinsic::mips_frint_w:
case Intrinsic::mips_frint_d:
return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1));

View File

@ -136,6 +136,46 @@ define void @fma_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
; CHECK: .size fma_v2f64
}
define void @fmsub_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
<4 x float>* %c) nounwind {
; CHECK: fmsub_v4f32:
%1 = load <4 x float>* %a
; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
%2 = load <4 x float>* %b
; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
%3 = load <4 x float>* %c
; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], 0($7)
%4 = fmul <4 x float> %2, %3
%5 = fsub <4 x float> %1, %4
; CHECK-DAG: fmsub.w [[R1]], [[R2]], [[R3]]
store <4 x float> %5, <4 x float>* %d
; CHECK-DAG: st.w [[R1]], 0($4)
ret void
; CHECK: .size fmsub_v4f32
}
define void @fmsub_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
<2 x double>* %c) nounwind {
; CHECK: fmsub_v2f64:
%1 = load <2 x double>* %a
; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
%2 = load <2 x double>* %b
; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
%3 = load <2 x double>* %c
; CHECK-DAG: ld.d [[R3:\$w[0-9]+]], 0($7)
%4 = fmul <2 x double> %2, %3
%5 = fsub <2 x double> %1, %4
; CHECK-DAG: fmsub.d [[R1]], [[R2]], [[R3]]
store <2 x double> %5, <2 x double>* %d
; CHECK-DAG: st.d [[R1]], 0($4)
ret void
; CHECK: .size fmsub_v2f64
}
define void @fdiv_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {
; CHECK: fdiv_v4f32: