aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2010-10-19 10:40:58 -0700
committerRichard Henderson <rth@gcc.gnu.org>2010-10-19 10:40:58 -0700
commit46935749db5e18fb1d88076b4093099e454a2b3f (patch)
tree27c93b1884d048e1981a5a3725fe426e06805f1f /gcc
parent16a1a239c289bb97157a1e1b50ba7b0e3d4a38be (diff)
downloadgcc-46935749db5e18fb1d88076b4093099e454a2b3f.zip
gcc-46935749db5e18fb1d88076b4093099e454a2b3f.tar.gz
gcc-46935749db5e18fb1d88076b4093099e454a2b3f.tar.bz2
Add FMA patterns for ia64.
From-SVN: r165702
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/ia64/ia64.md90
-rw-r--r--gcc/testsuite/gcc.target/ia64/builtin-fma-1.c25
-rw-r--r--gcc/testsuite/gcc.target/ia64/builtin-fma-2.c19
4 files changed, 140 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b58b5c..fdd86ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-19 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.md (fmasf4, *fmssf4, *nfmasf4): New.
+ (fmadf4, *fmsdf4, *nfmadf4): New.
+ (fmaxf4, *fmsxf4, *nfmaxf4): New.
+
2010-10-19 Michael Eager <eager@eagercon.com>
* config/microblaze/microblaze.c (TARGET_EXCEPT_UNWIND_INFO):
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index db1d2d2..73e57b6 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 0000000..a4b2e06
--- /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 0000000..16d95b7
--- /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); }