From 2fd6708c94d257db37220ea2ab3863cb11085bae Mon Sep 17 00:00:00 2001 From: rth Date: Tue, 19 Oct 2010 17:40:58 +0000 Subject: [PATCH] Add FMA patterns for ia64. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165702 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++ gcc/config/ia64/ia64.md | 90 +++++++++++++++++++++++++++ gcc/testsuite/gcc.target/ia64/builtin-fma-1.c | 25 ++++++++ gcc/testsuite/gcc.target/ia64/builtin-fma-2.c | 19 ++++++ 4 files changed, 140 insertions(+) create mode 100644 gcc/testsuite/gcc.target/ia64/builtin-fma-1.c create mode 100644 gcc/testsuite/gcc.target/ia64/builtin-fma-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b58b5c2cfc..fdd86cae2e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-10-19 Richard Henderson + + * config/ia64/ia64.md (fmasf4, *fmssf4, *nfmasf4): New. + (fmadf4, *fmsdf4, *nfmadf4): New. + (fmaxf4, *fmsxf4, *nfmaxf4): New. + 2010-10-19 Michael Eager * config/microblaze/microblaze.c (TARGET_EXCEPT_UNWIND_INFO): diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index db1d2d2f608..73e57b6cb33 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -2791,6 +2791,36 @@ "TARGET_FUSED_MADD" "fnma.s %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) + +;; Official C99 versions of the fmaf family of operations. +(define_insn "fmasf4" + [(set (match_operand:SF 0 "fr_register_operand" "=f") + (fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fma.s %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +(define_insn "*fmssf4" + [(set (match_operand:SF 0 "fr_register_operand" "=f") + (fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") + (neg:SF + (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))] + "" + "fms.s %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +;; This insn is officially "-(a * b) + c" which is "(-a * b) + c". +(define_insn "*nfmasf4" + [(set (match_operand:SF 0 "fr_register_operand" "=f") + (fma:SF (neg:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")) + (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fnma.s %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) ;; :::::::::::::::::::: ;; :: @@ -2977,6 +3007,36 @@ "TARGET_FUSED_MADD" "fnma.s %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) + +;; Official C99 versions of the fma family of operations. +(define_insn "fmadf4" + [(set (match_operand:DF 0 "fr_register_operand" "=f") + (fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fma.d %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +(define_insn "*fmsdf4" + [(set (match_operand:DF 0 "fr_register_operand" "=f") + (fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") + (neg:DF + (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))] + "" + "fms.d %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +;; See comment for nfmasf4. +(define_insn "*nfmadf4" + [(set (match_operand:DF 0 "fr_register_operand" "=f") + (fma:DF (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")) + (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fnma.d %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) ;; :::::::::::::::::::: ;; :: @@ -3234,6 +3294,36 @@ "TARGET_FUSED_MADD" "fnma.d %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) + +;; Official C99 versions of the fmal family of operations. +(define_insn "fmaxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fma %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +(define_insn "*fmsxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG") + (neg:XF + (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))] + "" + "fms %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +;; See comment for nfmasf4. +(define_insn "*nfmaxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (fma:XF (neg:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")) + (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ")))] + "" + "fnma %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) ;; :::::::::::::::::::: ;; :: diff --git a/gcc/testsuite/gcc.target/ia64/builtin-fma-1.c b/gcc/testsuite/gcc.target/ia64/builtin-fma-1.c new file mode 100644 index 00000000000..a4b2e063ce2 --- /dev/null +++ b/gcc/testsuite/gcc.target/ia64/builtin-fma-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ +/* Don't confuse the fma insn with the fma in the filename. */ +/* { dg-final { scan-assembler-times "fma\\." 4 } } */ +/* { dg-final { scan-assembler-times "fms" 2 } } */ +/* { dg-final { scan-assembler-times "fnma" 4 } } */ + +#ifndef __FP_FAST_FMAF +# error "__FP_FAST_FMAF should be defined" +#endif +#ifndef __FP_FAST_FMA +# error "__FP_FAST_FMA should be defined" +#endif + +float f0(float x, float y, float z) { return __builtin_fmaf(x,y,z); } +float f1(float x, float y, float z) { return __builtin_fmaf(x,y,-z); } +float f2(float x, float y, float z) { return __builtin_fmaf(-x,y,z); } +float f3(float x, float y, float z) { return __builtin_fmaf(x,-y,z); } +float f4(float x, float y, float z) { return __builtin_fmaf(-x,-y,z); } + +double d0(double x, double y, double z) { return __builtin_fma(x,y,z); } +double d1(double x, double y, double z) { return __builtin_fma(x,y,-z); } +double d2(double x, double y, double z) { return __builtin_fma(-x,y,z); } +double d3(double x, double y, double z) { return __builtin_fma(x,-y,z); } +double d4(double x, double y, double z) { return __builtin_fma(-x,-y,z); } diff --git a/gcc/testsuite/gcc.target/ia64/builtin-fma-2.c b/gcc/testsuite/gcc.target/ia64/builtin-fma-2.c new file mode 100644 index 00000000000..16d95b70ce4 --- /dev/null +++ b/gcc/testsuite/gcc.target/ia64/builtin-fma-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-skip-if "128-bit long double" { *-*-hpux* } { "*" } { "" } } */ +/* { dg-options "-O" } */ +/* Don't confuse the fma insn with the fma in the filename. */ +/* { dg-final { scan-assembler-times "fma\[ \]" 2 } } */ +/* { dg-final { scan-assembler-times "fms" 1 } } */ +/* { dg-final { scan-assembler-times "fnma" 2 } } */ + +#ifndef __FP_FAST_FMAL +# error "__FP_FAST_FMAL should be defined" +#endif + +typedef long double LD; + +LD L0(LD x, LD y, LD z) { return __builtin_fmal(x,y,z); } +LD L1(LD x, LD y, LD z) { return __builtin_fmal(x,y,-z); } +LD L2(LD x, LD y, LD z) { return __builtin_fmal(-x,y,z); } +LD L3(LD x, LD y, LD z) { return __builtin_fmal(x,-y,z); } +LD L4(LD x, LD y, LD z) { return __builtin_fmal(-x,-y,z); } -- 2.11.0