From 132e68c33c4bb48b6b9b99c4cada58e020ce67bd Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
Date: Thu, 20 Jul 2017 10:38:58 +0200
Subject: [PATCH] [SPARC] Add -mfslumd option

---
 gcc/config/sparc/freebsd.h    |  2 +-
 gcc/config/sparc/linux64.h    |  2 +-
 gcc/config/sparc/netbsd-elf.h |  3 ++-
 gcc/config/sparc/openbsd64.h  |  3 ++-
 gcc/config/sparc/sol2.h       |  4 ++--
 gcc/config/sparc/sp64-elf.h   |  3 ++-
 gcc/config/sparc/sparc.c      | 13 +++++++++----
 gcc/config/sparc/sparc.h      |  3 ++-
 gcc/config/sparc/sparc.md     |  2 +-
 gcc/config/sparc/sparc.opt    |  4 ++++
 gcc/doc/invoke.texi           |  9 ++++++++-
 11 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
index 3e7ea6c9d17..c718e9e5cd8 100644
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -82,7 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef  TARGET_DEFAULT
 #define TARGET_DEFAULT \
   (MASK_V9 + MASK_64BIT + MASK_PTR64 /* + MASK_FASTER_STRUCTS */ \
-   + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU \
+   + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_FSMULD \
    + MASK_LONG_DOUBLE_128 /* + MASK_HARD_QUAD */)
 
 /* The default code model.  */
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index 573ce8a9a4c..4f9d4e835b8 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
   (MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_STACK_BIAS + \
-   MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+   MASK_APP_REGS + MASK_FPU + MASK_FSMULD + MASK_LONG_DOUBLE_128)
 #endif
 
 /* This must be v9a not just v9 because by default we enable
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
index 9d670cff8ac..c25998434db 100644
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -96,7 +96,8 @@ along with GCC; see the file COPYING3.  If not see
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
   (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \
-   + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+   + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_FSMULD \
+   + MASK_LONG_DOUBLE_128)
 
 #undef SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL CM_MEDANY
diff --git a/gcc/config/sparc/openbsd64.h b/gcc/config/sparc/openbsd64.h
index e8a8abccde6..ec5d782c834 100644
--- a/gcc/config/sparc/openbsd64.h
+++ b/gcc/config/sparc/openbsd64.h
@@ -21,7 +21,8 @@ along with GCC; see the file COPYING3.  If not see
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
 (MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_HARD_QUAD \
- + MASK_APP_REGS + MASK_FPU + MASK_STACK_BIAS + MASK_LONG_DOUBLE_128)
+ + MASK_APP_REGS + MASK_FPU + MASK_FSMULD + MASK_STACK_BIAS \
+ + MASK_LONG_DOUBLE_128)
 
 #undef SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL CM_MEDMID
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index b8177c0b692..567466be4c9 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -26,10 +26,10 @@ along with GCC; see the file COPYING3.  If not see
 #ifdef TARGET_64BIT_DEFAULT
 #define TARGET_DEFAULT \
   (MASK_V9 + MASK_64BIT + MASK_PTR64 + MASK_STACK_BIAS + \
-   MASK_V8PLUS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+   MASK_V8PLUS + MASK_APP_REGS + MASK_FPU + MASK_FSMULD + MASK_LONG_DOUBLE_128)
 #else
 #define TARGET_DEFAULT \
-  (MASK_V8PLUS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+  (MASK_V8PLUS + MASK_APP_REGS + MASK_FPU + MASK_FSMULD + MASK_LONG_DOUBLE_128)
 #endif
 
 /* The default code model used to be CM_MEDANY on Solaris
diff --git a/gcc/config/sparc/sp64-elf.h b/gcc/config/sparc/sp64-elf.h
index 8b0b0788185..0e98af60c46 100644
--- a/gcc/config/sparc/sp64-elf.h
+++ b/gcc/config/sparc/sp64-elf.h
@@ -22,7 +22,8 @@ along with GCC; see the file COPYING3.  If not see
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
 (MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_HARD_QUAD \
- + MASK_APP_REGS + MASK_FPU + MASK_STACK_BIAS + MASK_LONG_DOUBLE_128)
+ + MASK_APP_REGS + MASK_FPU + MASK_FSMULD + MASK_STACK_BIAS \
+ + MASK_LONG_DOUBLE_128)
 
 #undef SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL CM_EMBMEDANY
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index f4f318a81a1..55c42c417e8 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1304,6 +1304,8 @@ dump_target_flag_bits (const int flags)
     fprintf (stderr, "FLAT ");
   if (flags & MASK_FMAF)
     fprintf (stderr, "FMAF ");
+  if (flags & MASK_FSMULD)
+    fprintf (stderr, "FSMULD ");
   if (flags & MASK_FPU)
     fprintf (stderr, "FPU ");
   if (flags & MASK_HARD_QUAD)
@@ -1408,9 +1410,9 @@ sparc_option_override (void)
     { "v8",		MASK_ISA, MASK_V8 },
     /* TI TMS390Z55 supersparc */
     { "supersparc",	MASK_ISA, MASK_V8 },
-    { "hypersparc",	MASK_ISA, MASK_V8|MASK_FPU },
+    { "hypersparc",	MASK_ISA, MASK_V8|MASK_FPU|MASK_FSMULD },
     { "leon",		MASK_ISA, MASK_V8|MASK_LEON|MASK_FPU },
-    { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU },
+    { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU|MASK_FSMULD },
     { "leon3v7",	MASK_ISA, MASK_LEON3|MASK_FPU },
     { "sparclite",	MASK_ISA, MASK_SPARCLITE },
     /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
@@ -1603,11 +1605,11 @@ sparc_option_override (void)
   if (TARGET_VIS4B)
     target_flags |= MASK_VIS4 | MASK_VIS3 | MASK_VIS2 | MASK_VIS;
 
-  /* Don't allow -mvis, -mvis2, -mvis3, -mvis4, -mvis4b and -mfmaf if
+  /* Don't allow -mvis, -mvis2, -mvis3, -mvis4, -mvis4b, -mfmaf and -mfsmuld if
      FPU is disabled.  */
   if (! TARGET_FPU)
     target_flags &= ~(MASK_VIS | MASK_VIS2 | MASK_VIS3 | MASK_VIS4
-		      | MASK_VIS4B | MASK_FMAF);
+		      | MASK_VIS4B | MASK_FMAF | MASK_FSMULD);
 
   /* -mvis assumes UltraSPARC+, so we are sure v9 instructions
      are available; -m64 also implies v9.  */
@@ -1641,6 +1643,9 @@ sparc_option_override (void)
   if (sparc_fix_ut699 || sparc_fix_ut700 || sparc_fix_gr712rc)
     sparc_fix_b2bst = 1;
 
+  if (sparc_fix_ut699)
+    target_flags &= ~MASK_FSMULD;
+
   /* Supply a default value for align_functions.  */
   if (align_functions == 0)
     {
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index d7c617e06c3..15a62179af5 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -438,7 +438,8 @@ extern enum cmodel sparc_cmodel;
 /* Mask of all CPU feature flags.  */
 #define MASK_FEATURES						\
   (MASK_FPU + MASK_HARD_QUAD + MASK_VIS + MASK_VIS2 + MASK_VIS3	\
-   + MASK_VIS4 + MASK_CBCOND + MASK_FMAF + MASK_POPC + MASK_SUBXC)
+   + MASK_VIS4 + MASK_CBCOND + MASK_FMAF + MASK_FSMULD		\
+   + MASK_POPC + MASK_SUBXC)
  
 /* TARGET_HARD_MUL: Use 32-bit hardware multiply instructions but not %y.  */
 #define TARGET_HARD_MUL				\
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index b154003c54a..751bacdbcac 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -6121,7 +6121,7 @@ visl")
   [(set (match_operand:DF 0 "register_operand" "=e")
 	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
 		 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
-  "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
+  "TARGET_FSMULD"
   "fsmuld\t%1, %2, %0"
   [(set_attr "type" "fpmul")
    (set_attr "fptype" "double")])
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index ae63d2018e3..7a582f3a870 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -93,6 +93,10 @@ mfmaf
 Target Report Mask(FMAF)
 Use UltraSPARC Fused Multiply-Add extensions.
 
+mfsmuld
+Target Report Mask(FSMULD)
+Use V8+ Floating-point Multiply Single to Double (FsMULd) instruction.
+
 mpopc
 Target Report Mask(POPC)
 Use UltraSPARC Population-Count instruction.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4926c90e772..8515bca1614 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1124,7 +1124,7 @@ See RS/6000 and PowerPC Options.
 -mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
 -mvis2  -mno-vis2  -mvis3  -mno-vis3 @gol
 -mvis4 -mno-vis4 -mvis4b -mno-vis4b @gol
--mcbcond  -mno-cbcond  -mfmaf  -mno-fmaf  @gol
+-mcbcond  -mno-cbcond  -mfmaf  -mno-fmaf  -mfsmuld  -mno-fsmuld  @gol
 -mpopc  -mno-popc  -msubxc  -mno-subxc @gol
 -mfix-at697f  -mfix-ut699  -mfix-ut700  -mfix-gr712rc @gol
 -mlra  -mno-lra}
@@ -24041,6 +24041,13 @@ Fused Multiply-Add Floating-point instructions.  The default is @option{-mfmaf}
 when targeting a CPU that supports such instructions, such as Niagara-3 and
 later.
 
+@item -mfsmuld
+@itemx -mno-fsmuld
+@opindex mfsmuld
+@opindex mno-fsmuld
+With @option{-mfsmuld}, GCC generates code that takes advantage of the V8+
+Floating-point Multiply Single to Double (FsMULd) instruction.
+
 @item -mpopc
 @itemx -mno-popc
 @opindex mpopc
-- 
2.12.3

