CurDAG->getTargetFrameIndex(FI, MVT::i32),
getI32Imm(0));
}
- case ISD::FADD: {
- MVT::ValueType Ty = N->getValueType(0);
- if (!NoExcessFPPrecision) { // Match FMA ops
- if (N->getOperand(0).getOpcode() == ISD::FMUL &&
- N->getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD :PPC::FMADDS,
- Ty, Select(N->getOperand(0).getOperand(0)),
- Select(N->getOperand(0).getOperand(1)),
- Select(N->getOperand(1)));
- } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD :PPC::FMADDS,
- Ty, Select(N->getOperand(1).getOperand(0)),
- Select(N->getOperand(1).getOperand(1)),
- Select(N->getOperand(0)));
- }
- }
-
- // Other cases are autogenerated.
- break;
- }
- case ISD::FSUB: {
- MVT::ValueType Ty = N->getValueType(0);
-
- if (!NoExcessFPPrecision) { // Match FMA ops
- if (N->getOperand(0).getOpcode() == ISD::FMUL &&
- N->getOperand(0).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB:PPC::FMSUBS,
- Ty, Select(N->getOperand(0).getOperand(0)),
- Select(N->getOperand(0).getOperand(1)),
- Select(N->getOperand(1)));
- } else if (N->getOperand(1).getOpcode() == ISD::FMUL &&
- N->getOperand(1).Val->hasOneUse()) {
- ++FusedFP; // Statistic
- return CurDAG->SelectNodeTo(N, Ty == MVT::f64 ?PPC::FNMSUB:PPC::FNMSUBS,
- Ty, Select(N->getOperand(1).getOperand(0)),
- Select(N->getOperand(1).getOperand(1)),
- Select(N->getOperand(0)));
- }
- }
-
- // Other cases are autogenerated.
- break;
- }
case ISD::SDIV: {
// FIXME: since this depends on the setting of the carry flag from the srawi
// we should really be making notes about that for the scheduler.
//===----------------------------------------------------------------------===//
// PowerPC Instruction Predicate Definitions.
-def FPContractions : Predicate<"!NoExcessFPPrecision">;
+def FPContractions : Predicate<"NoExcessFPPrecision">;
//===----------------------------------------------------------------------===//
// PowerPC Instruction Definitions.
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
"fnmadd $FRT, $FRA, $FRC, $FRB", FPFused,
[(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
- F8RC:$FRB)))]>;
+ F8RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMADDS : AForm_1<59, 31,
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
"fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
[(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC),
- F4RC:$FRB)))]>;
+ F4RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMSUB : AForm_1<63, 30,
(ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
"fnmsub $FRT, $FRA, $FRC, $FRB", FPFused,
[(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
- F8RC:$FRB)))]>;
+ F8RC:$FRB)))]>,
+ Requires<[FPContractions]>;
def FNMSUBS : AForm_1<59, 30,
(ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
"fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
[(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC),
- F4RC:$FRB)))]>;
+ F4RC:$FRB)))]>,
+ Requires<[FPContractions]>;
// FSEL is artificially split into 4 and 8-byte forms for the result. To avoid
// having 4 of these, force the comparison to always be an 8-byte double (code
// should use an FMRSD if the input comparison value really wants to be a float)
def VMADDFP : VAForm_1<46, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
"vmaddfp $vD, $vA, $vC, $vB", VecFP,
[(set VRRC:$vD, (fadd (fmul VRRC:$vA, VRRC:$vC),
- VRRC:$vB))]>;
+ VRRC:$vB))]>,
+ Requires<[FPContractions]>;
def VNMSUBFP: VAForm_1<47, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
- "vnmsubfp $vD, $vA, $vC, $vB", VecFP,
- [(set VRRC:$vD, (fneg (fsub (fmul VRRC:$vA,
- VRRC:$vC),
- VRRC:$vB)))]>;
+ "vnmsubfp $vD, $vA, $vC, $vB", VecFP,
+ [(set VRRC:$vD, (fneg (fsub (fmul VRRC:$vA,
+ VRRC:$vC),
+ VRRC:$vB)))]>,
+ Requires<[FPContractions]>;
// VX-Form instructions. AltiVec arithmetic ops.
def VADDFP : VXForm_1<10, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
def : Pat<(fmul VRRC:$vA, VRRC:$vB),
(VMADDFP VRRC:$vA, (V_SET0), VRRC:$vB)>;
+// Fused negative multiply subtract, alternate pattern
+def : Pat<(fsub F8RC:$B, (fmul F8RC:$A, F8RC:$C)),
+ (FNMSUB F8RC:$A, F8RC:$C, F8RC:$B)>,
+ Requires<[FPContractions]>;
+def : Pat<(fsub F4RC:$B, (fmul F4RC:$A, F4RC:$C)),
+ (FNMSUBS F4RC:$A, F4RC:$C, F4RC:$B)>,
+ Requires<[FPContractions]>;
+
// Fused multiply add and multiply sub for packed float. These are represented
// separately from the real instructions above, for operations that must have
// the additional precision, such as Newton-Rhapson (used by divide, sqrt)