Add support for floating-point fused multiply-add on Sparc.
authorDavid S. Miller <davem@davemloft.net>
Sun, 25 Sep 2011 21:28:51 +0000 (21:28 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Sun, 25 Sep 2011 21:28:51 +0000 (14:28 -0700)
* configure.ac: Add feature check to make sure the assembler
supports the FMAF, HPC, and VIS 3.0 instructions found on
Niagara-3 and later cpus.
* configure: Rebuild.
* config.in: Likewise.
* config/sparc/sparc.opt: New option '-mfmaf'.
* config/sparc/sparc.md: Add float fused multiply-add patterns.
* config/sparc/sparc.h (AS_NIAGARA3_FLAG): New macro.
(ASM_CPU64_DEFAULT_SPEC, ASM_CPU_SPEC): Use it, as needed.
* config/sparc/sol2.h (ASM_CPU32_DEFAULT_SPEC,
ASM_CPU64_DEFAULT_SPEC, ASM_CPU_SPEC): Likewise.
* config/sparc/sparc.c (sparc_option_override): Turn MASK_FMAF on
by default for Niagara-3 and later.  Turn it off if TARGET_FPU is
disabled.
(sparc_rtx_costs): Handle 'FMA'.
* doc/invoke.texi: Document -mfmaf.

From-SVN: r179174

gcc/ChangeLog
gcc/config.in
gcc/config/sparc/sol2.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/config/sparc/sparc.opt
gcc/configure
gcc/configure.ac
gcc/doc/invoke.texi

index 4c286fcda83466240487b53d935d9db41cb5a213..848cb32573db7e383f410fb40ca34044744a29f8 100644 (file)
        (movdf_insn_sp32_v9): Likewise.
        (movdf_insn_sp64): Likewise.
 
+       * configure.ac: Add feature check to make sure the assembler
+       supports the FMAF, HPC, and VIS 3.0 instructions found on
+       Niagara-3 and later cpus.
+       * configure: Rebuild.
+       * config.in: Likewise.
+       * config/sparc/sparc.opt: New option '-mfmaf'.
+       * config/sparc/sparc.md: Add float fused multiply-add patterns.
+       * config/sparc/sparc.h (AS_NIAGARA3_FLAG): New macro.
+       (ASM_CPU64_DEFAULT_SPEC, ASM_CPU_SPEC): Use it, as needed.
+       * config/sparc/sol2.h (ASM_CPU32_DEFAULT_SPEC,
+       ASM_CPU64_DEFAULT_SPEC, ASM_CPU_SPEC): Likewise.
+       * config/sparc/sparc.c (sparc_option_override): Turn MASK_FMAF on
+       by default for Niagara-3 and later.  Turn it off if TARGET_FPU is
+       disabled.
+       (sparc_rtx_costs): Handle 'FMA'.
+       * doc/invoke.texi: Document -mfmaf.
+
 2011-09-25  Jakub Jelinek  <jakub@redhat.com>
 
        * tree-ssa-structalias.c (intra_create_variable_infos): Treat
index d202b038e6eee914d3b9234e591269499a80e9ef..d9b9805a2a99a8fa7f4f69c6da1c0f747ba94ee1 100644 (file)
 #endif
 
 
+/* Define if your assembler supports FMAF, HPC, and VIS 3.0 instructions. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_FMAF_HPC_VIS3
+#endif
+
+
 /* Define if your assembler supports fprnd. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_FPRND
 #endif
 
 
-/* Define if _Unwind_GetIPInfo is available. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_GETIPINFO
-#endif
-
-
 /* Define to 1 if you have the `getrlimit' function. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_GETRLIMIT
index bd58c9f8c7b8b14def2762079738bd34811ba059..fea60d0543b2add4c49254697a9c8a67c89a4cb9 100644 (file)
@@ -125,9 +125,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef CPP_CPU64_DEFAULT_SPEC
 #define CPP_CPU64_DEFAULT_SPEC ""
 #undef ASM_CPU32_DEFAULT_SPEC
-#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusb"
+#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plus" AS_NIAGARA3_FLAG
 #undef ASM_CPU64_DEFAULT_SPEC
-#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b"
+#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG AS_NIAGARA3_FLAG
 #undef ASM_CPU_DEFAULT_SPEC
 #define ASM_CPU_DEFAULT_SPEC ASM_CPU32_DEFAULT_SPEC
 #endif
@@ -240,8 +240,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 %{mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
 %{mcpu=niagara:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
 %{mcpu=niagara2:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
-%{mcpu=niagara3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
-%{mcpu=niagara4:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
+%{mcpu=niagara3:" DEF_ARCH32_SPEC("-xarch=v8plus" AS_NIAGARA3_FLAG) DEF_ARCH64_SPEC(AS_SPARC64_FLAG AS_NIAGARA3_FLAG) "} \
+%{mcpu=niagara4:" DEF_ARCH32_SPEC("-xarch=v8plus" AS_NIAGARA3_FLAG) DEF_ARCH64_SPEC(AS_SPARC64_FLAG AS_NIAGARA3_FLAG) "} \
 %{!mcpu=niagara4:%{!mcpu=niagara3:%{!mcpu=niagara2:%{!mcpu=niagara:%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}}}}}} \
 %{!mcpu*:%(asm_cpu_default)} \
 "
index 344637935d505f83d6fe687f5e2bdbf6b9cf005c..8193d1cf4889772ce1c97f35ce76b16834b5f03a 100644 (file)
@@ -776,9 +776,9 @@ sparc_option_override (void)
     /* UltraSPARC T2 */
     { MASK_ISA, MASK_V9},
     /* UltraSPARC T3 */
-    { MASK_ISA, MASK_V9},
+    { MASK_ISA, MASK_V9 | MASK_FMAF},
     /* UltraSPARC T4 */
-    { MASK_ISA, MASK_V9},
+    { MASK_ISA, MASK_V9 | MASK_FMAF},
   };
   const struct cpu_table *cpu;
   unsigned int i;
@@ -857,9 +857,9 @@ sparc_option_override (void)
   if (target_flags_explicit & MASK_FPU)
     target_flags = (target_flags & ~MASK_FPU) | fpu;
 
-  /* Don't allow -mvis if FPU is disabled.  */
+  /* Don't allow -mvis or -mfmaf if FPU is disabled.  */
   if (! TARGET_FPU)
-    target_flags &= ~MASK_VIS;
+    target_flags &= ~(MASK_VIS | MASK_FMAF);
 
   /* -mvis assumes UltraSPARC+, so we are sure v9 instructions
      are available.
@@ -9646,6 +9646,25 @@ sparc_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
        *total = COSTS_N_INSNS (1);
       return false;
 
+    case FMA:
+      {
+       rtx sub;
+
+       gcc_assert (float_mode_p);
+       *total = sparc_costs->float_mul;
+
+       sub = XEXP (x, 0);
+       if (GET_CODE (sub) == NEG)
+         sub = XEXP (sub, 0);
+       *total += rtx_cost (sub, FMA, 0, speed);
+
+       sub = XEXP (x, 2);
+       if (GET_CODE (sub) == NEG)
+         sub = XEXP (sub, 0);
+       *total += rtx_cost (sub, FMA, 2, speed);
+       return true;
+      }
+
     case MULT:
       if (float_mode_p)
        *total = sparc_costs->float_mul;
index 77eff2e6bbfea16ef01eb5036832572b1c3ad29d..ad1e0eff4356b6de1b715a7aed5a910511dc702e 100644 (file)
@@ -287,11 +287,11 @@ extern enum cmodel sparc_cmodel;
 #endif
 #if TARGET_CPU_DEFAULT == TARGET_CPU_niagara3
 #define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
-#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9" AS_NIAGARA3_FLAG
 #endif
 #if TARGET_CPU_DEFAULT == TARGET_CPU_niagara4
 #define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
-#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9" AS_NIAGARA3_FLAG
 #endif
 
 #else
@@ -431,8 +431,8 @@ extern enum cmodel sparc_cmodel;
 %{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
 %{mcpu=niagara:%{!mv8plus:-Av9b}} \
 %{mcpu=niagara2:%{!mv8plus:-Av9b}} \
-%{mcpu=niagara3:%{!mv8plus:-Av9b}} \
-%{mcpu=niagara4:%{!mv8plus:-Av9b}} \
+%{mcpu=niagara3:%{!mv8plus:-Av9" AS_NIAGARA3_FLAG "}} \
+%{mcpu=niagara4:%{!mv8plus:-Av9" AS_NIAGARA3_FLAG "}} \
 %{!mcpu*:%(asm_cpu_default)} \
 "
 
@@ -1882,6 +1882,14 @@ extern int sparc_indent_opcode;
 #define TARGET_SUN_TLS TARGET_TLS
 #define TARGET_GNU_TLS 0
 
+#ifndef HAVE_AS_FMAF_HPC_VIS3
+#define AS_NIAGARA3_FLAG "b"
+#undef TARGET_FMAF
+#define TARGET_FMAF 0
+#else
+#define AS_NIAGARA3_FLAG "d"
+#endif
+
 /* The number of Pmode words for the setjmp buffer.  */
 #define JMP_BUF_SIZE 12
 
index f830a3936eef26def38e791312bc6606aa52f0a7..3f7a93b6b7508ac9776d7596a86854abe79fc952 100644 (file)
   "fmuls\t%1, %2, %0"
   [(set_attr "type" "fpmul")])
 
+(define_insn "fmadf4"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+        (fma:DF (match_operand:DF 1 "register_operand" "e")
+               (match_operand:DF 2 "register_operand" "e")
+               (match_operand:DF 3 "register_operand" "e")))]
+  "TARGET_FMAF"
+  "fmaddd\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "fmsdf4"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+        (fma:DF (match_operand:DF 1 "register_operand" "e")
+               (match_operand:DF 2 "register_operand" "e")
+               (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
+  "TARGET_FMAF"
+  "fmsubd\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "*nfmadf4"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+        (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
+                       (match_operand:DF 2 "register_operand" "e")
+                       (match_operand:DF 3 "register_operand" "e"))))]
+  "TARGET_FMAF"
+  "fnmaddd\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "*nfmsdf4"
+  [(set (match_operand:DF 0 "register_operand" "=e")
+        (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
+                       (match_operand:DF 2 "register_operand" "e")
+                       (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
+  "TARGET_FMAF"
+  "fnmsubd\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "fmasf4"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (fma:SF (match_operand:SF 1 "register_operand" "f")
+               (match_operand:SF 2 "register_operand" "f")
+               (match_operand:SF 3 "register_operand" "f")))]
+  "TARGET_FMAF"
+  "fmadds\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "fmssf4"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (fma:SF (match_operand:SF 1 "register_operand" "f")
+               (match_operand:SF 2 "register_operand" "f")
+               (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
+  "TARGET_FMAF"
+  "fmsubs\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "*nfmasf4"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
+                       (match_operand:SF 2 "register_operand" "f")
+                       (match_operand:SF 3 "register_operand" "f"))))]
+  "TARGET_FMAF"
+  "fnmadds\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
+(define_insn "*nfmssf4"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
+                       (match_operand:SF 2 "register_operand" "f")
+                       (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
+  "TARGET_FMAF"
+  "fnmsubs\t%1, %2, %3, %0"
+  [(set_attr "type" "fpmul")])
+
 (define_insn "*muldf3_extend"
   [(set (match_operand:DF 0 "register_operand" "=e")
        (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
index ce6fa94fde83b8af1e1380b488a56396df6c6bfc..6be6a7590d0439357ce0e2c8b92b6b1b067f51ae 100644 (file)
@@ -61,6 +61,10 @@ mvis
 Target Report Mask(VIS)
 Use UltraSPARC Visual Instruction Set extensions
 
+mfmaf
+Target Report Mask(FMAF)
+Use UltraSPARC Fused Multiply-Add extensions
+
 mptr64
 Target Report RejectNegative Mask(PTR64)
 Pointers are 64-bit
index 651471ca9c8be1e065e352acf5546a8db1d922d7..c1838813ed97f6ee19dd566328395c371483a24f 100755 (executable)
@@ -24042,6 +24042,42 @@ if test $gcc_cv_as_sparc_offsetable_lo10 = yes; then
 
 $as_echo "#define HAVE_AS_OFFSETABLE_LO10 1" >>confdefs.h
 
+fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for FMAF, HPC, and VIS 3.0 instructions" >&5
+$as_echo_n "checking assembler for FMAF, HPC, and VIS 3.0 instructions... " >&6; }
+if test "${gcc_cv_as_sparc_fmaf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_sparc_fmaf=no
+  if test x$gcc_cv_as != x; then
+    $as_echo '.text
+       .align 4
+       fmaddd %f0, %f2, %f4, %f6
+       addxccc %g1, %g2, %g3
+       fsrl32 %f2, %f4, %f8
+       fnaddd %f10, %f12, %f14' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags -xarch=v9d -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+       gcc_cv_as_sparc_fmaf=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_fmaf" >&5
+$as_echo "$gcc_cv_as_sparc_fmaf" >&6; }
+if test $gcc_cv_as_sparc_fmaf = yes; then
+
+$as_echo "#define HAVE_AS_FMAF_HPC_VIS3 1" >>confdefs.h
+
 fi
     ;;
 
index 126cb1964507dff5b23f355e61ee32d05277e3a1..8069e6ac5595d27f6da3a03fa3b68c74c6ac976c 100644 (file)
@@ -3478,6 +3478,18 @@ foo:
        fi],
        [AC_DEFINE(HAVE_AS_OFFSETABLE_LO10, 1,
                 [Define if your assembler supports offsetable %lo().])])
+
+    gcc_GAS_CHECK_FEATURE([FMAF, HPC, and VIS 3.0 instructions],
+      gcc_cv_as_sparc_fmaf,,
+      [-xarch=v9d],
+      [.text
+       .align 4
+       fmaddd %f0, %f2, %f4, %f6
+       addxccc %g1, %g2, %g3
+       fsrl32 %f2, %f4, %f8
+       fnaddd %f10, %f12, %f14],,
+      [AC_DEFINE(HAVE_AS_FMAF_HPC_VIS3, 1,
+                [Define if your assembler supports FMAF, HPC, and VIS 3.0 instructions.])])
     ;;
 
 changequote(,)dnl
index 957d75ce964a247e87f2ecdc0c04fff15ce446ac..1f04612c7aa9536b626dd83d791b370f72fa51a4 100644 (file)
@@ -879,7 +879,8 @@ See RS/6000 and PowerPC Options.
 -mlittle-endian @gol
 -mstack-bias  -mno-stack-bias @gol
 -munaligned-doubles  -mno-unaligned-doubles @gol
--mv8plus  -mno-v8plus  -mvis  -mno-vis}
+-mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
+-mfmaf -mno-fmaf}
 
 @emph{SPU Options}
 @gccoptlist{-mwarn-reloc -merror-reloc @gol
@@ -17397,6 +17398,15 @@ mode for all SPARC-V9 processors.
 @opindex mno-vis
 With @option{-mvis}, GCC generates code that takes advantage of the UltraSPARC
 Visual Instruction Set extensions.  The default is @option{-mno-vis}.
+
+@item -mfmaf
+@itemx -mno-fmaf
+@opindex mfmaf
+@opindex mno-fmaf
+With @option{-mfmaf}, GCC generates code that takes advantage of the UltraSPARC
+Fused Multiply-Add Floating-point extensions.  The default is @option{-mfmaf}
+when targetting a cpu that supports such instructions, such as Niagara-3 and
+later.
 @end table
 
 These @samp{-m} options are supported in addition to the above