diff mbox

[2/2,SPARC] Add -mfsmuld option

Message ID 20170726064700.19720-2-sebastian.huber@embedded-brains.de
State New
Headers show

Commit Message

Sebastian Huber July 26, 2017, 6:47 a.m. UTC
Add the -mfsmuld option to control the generation of the FsMULd
instruction.  In general, this instruction is available in architecture
version V8 and V9 CPUs with FPU.  Some CPUs of this category do not
support this instruction properly, e.g. AT697E, AT697F and UT699.  Some
CPUs of this category do not implement it in hardware, e.g. LEON3/4 with
GRFPU-lite.

gcc/
	* config/sparc/sparc.c (dump_target_flag_bits): Dump MASK_FSMULD.
	(sparc_option_override): Honour MASK_FSMULD.
	* config/sparc/sparc.h (MASK_FEATURES): Add MASK_FSMULD.
	* config/sparc/sparc.md (muldf3_extend): Use TARGET_FSMULD.
	* config/sparc/sparc.opt (mfsmuld): New option.
	* doc/invoke.texi (mfsmuld): Document option.
---
 gcc/config/sparc/sparc.c   | 38 ++++++++++++++++++++++----------------
 gcc/config/sparc/sparc.h   |  3 ++-
 gcc/config/sparc/sparc.md  |  2 +-
 gcc/config/sparc/sparc.opt |  4 ++++
 gcc/doc/invoke.texi        | 11 ++++++++++-
 5 files changed, 39 insertions(+), 19 deletions(-)

Comments

Eric Botcazou July 26, 2017, 8:09 a.m. UTC | #1
> Add the -mfsmuld option to control the generation of the FsMULd
> instruction.  In general, this instruction is available in architecture
> version V8 and V9 CPUs with FPU.  Some CPUs of this category do not
> support this instruction properly, e.g. AT697E, AT697F and UT699.  Some
> CPUs of this category do not implement it in hardware, e.g. LEON3/4 with
> GRFPU-lite.

OK on principle, but could we avoid all this shuffling with MASK_FSMULD?  
Having to write MASK_V8|MASK_FSMULD and MASK_V9|MASK_FSMULD is awkward.

What about automatically setting MASK_FSMULD if MASK_FPU is set and disabling 
it by default for v7, cypress and leon (i.e MASK_ISA|MASK_FSMULD for them)?
Sebastian Huber July 26, 2017, 8:13 a.m. UTC | #2
On 26/07/17 10:09, Eric Botcazou wrote:

>> Add the -mfsmuld option to control the generation of the FsMULd
>> instruction.  In general, this instruction is available in architecture
>> version V8 and V9 CPUs with FPU.  Some CPUs of this category do not
>> support this instruction properly, e.g. AT697E, AT697F and UT699.  Some
>> CPUs of this category do not implement it in hardware, e.g. LEON3/4 with
>> GRFPU-lite.
> OK on principle, but could we avoid all this shuffling with MASK_FSMULD?
> Having to write MASK_V8|MASK_FSMULD and MASK_V9|MASK_FSMULD is awkward.
>
> What about automatically setting MASK_FSMULD if MASK_FPU is set and disabling
> it by default for v7, cypress and leon (i.e MASK_ISA|MASK_FSMULD for them)?

That was my first approach, however, this didn't work well. The 
-fno-fsmuld option didn't work here and was ignored. I guess this is due 
to the asymmetric handling of the enable/disable CPU target flags 
handling with respect to the target_flags_explicit:

   target_flags &= ~cpu->disable;
   target_flags |= (cpu->enable
#ifndef HAVE_AS_FMAF_HPC_VIS3
            & ~(MASK_FMAF | MASK_VIS3)
#endif
#ifndef HAVE_AS_SPARC4
            & ~MASK_CBCOND
#endif
#ifndef HAVE_AS_SPARC5_VIS4
            & ~(MASK_VIS4 | MASK_SUBXC)
#endif
#ifndef HAVE_AS_SPARC6
            & ~(MASK_VIS4B)
#endif
#ifndef HAVE_AS_LEON
            & ~(MASK_LEON | MASK_LEON3)
#endif
            & ~(target_flags_explicit & MASK_FEATURES)
            );
Sebastian Huber July 26, 2017, 8:17 a.m. UTC | #3
On 26/07/17 10:13, Sebastian Huber wrote:

> On 26/07/17 10:09, Eric Botcazou wrote:
>
>>> Add the -mfsmuld option to control the generation of the FsMULd
>>> instruction.  In general, this instruction is available in architecture
>>> version V8 and V9 CPUs with FPU.  Some CPUs of this category do not
>>> support this instruction properly, e.g. AT697E, AT697F and UT699.  Some
>>> CPUs of this category do not implement it in hardware, e.g. LEON3/4 
>>> with
>>> GRFPU-lite.
>> OK on principle, but could we avoid all this shuffling with MASK_FSMULD?
>> Having to write MASK_V8|MASK_FSMULD and MASK_V9|MASK_FSMULD is awkward.
>>
>> What about automatically setting MASK_FSMULD if MASK_FPU is set and 
>> disabling
>> it by default for v7, cypress and leon (i.e MASK_ISA|MASK_FSMULD for 
>> them)?
>
> That was my first approach, however, this didn't work well. The 
> -fno-fsmuld option didn't work here and was ignored. I guess this is 
> due to the asymmetric handling of the enable/disable CPU target flags 
> handling with respect to the target_flags_explicit:
>
>   target_flags &= ~cpu->disable;
>   target_flags |= (cpu->enable
> #ifndef HAVE_AS_FMAF_HPC_VIS3
>            & ~(MASK_FMAF | MASK_VIS3)
> #endif
> #ifndef HAVE_AS_SPARC4
>            & ~MASK_CBCOND
> #endif
> #ifndef HAVE_AS_SPARC5_VIS4
>            & ~(MASK_VIS4 | MASK_SUBXC)
> #endif
> #ifndef HAVE_AS_SPARC6
>            & ~(MASK_VIS4B)
> #endif
> #ifndef HAVE_AS_LEON
>            & ~(MASK_LEON | MASK_LEON3)
> #endif
>            & ~(target_flags_explicit & MASK_FEATURES)
>            );
>

I will try it again using

target_flags |= MASK_FSMULD & ~target_flags_explicit;

before this block above.

If !TARGET_FPU, this flag is cleared later.
Sebastian Huber July 26, 2017, 8:44 a.m. UTC | #4
On 26/07/17 10:09, Eric Botcazou wrote:

> What about automatically setting MASK_FSMULD if MASK_FPU is set and disabling
> it by default for v7, cypress and leon (i.e MASK_ISA|MASK_FSMULD for them)?

What about the SPARCLITE and SPARCLET processors? I guess they 
previously didn't use the FSMULD due to the (TARGET_V8 || TARGET_9) && 
TARGET_FPU. I have now:

     { "sparclite",    MASK_ISA|MASK_FSMULD, MASK_SPARCLITE },
     /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
     { "f930",        MASK_ISA|MASK_FPU, MASK_SPARCLITE },
     /* The Fujitsu MB86934 is the recent sparclite chip, with an FPU.  */
     { "f934",        MASK_ISA|MASK_FSMULD, MASK_SPARCLITE },
     { "sparclite86x",    MASK_ISA|MASK_FPU, MASK_SPARCLITE },
     { "sparclet",    MASK_ISA|MASK_FSMULD, MASK_SPARCLET },
     /* TEMIC sparclet */
     { "tsc701",        MASK_ISA|MASK_FSMULD, MASK_SPARCLET },
diff mbox

Patch

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 674a3823cb9..832e9945cd6 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)
@@ -1405,12 +1407,12 @@  sparc_option_override (void)
   } const cpu_table[] = {
     { "v7",		MASK_ISA, 0 },
     { "cypress",	MASK_ISA, 0 },
-    { "v8",		MASK_ISA, MASK_V8 },
+    { "v8",		MASK_ISA, MASK_V8|MASK_FSMULD },
     /* TI TMS390Z55 supersparc */
-    { "supersparc",	MASK_ISA, MASK_V8 },
-    { "hypersparc",	MASK_ISA, MASK_V8 },
+    { "supersparc",	MASK_ISA, MASK_V8|MASK_FSMULD },
+    { "hypersparc",	MASK_ISA, MASK_V8|MASK_FSMULD },
     { "leon",		MASK_ISA, MASK_V8|MASK_LEON },
-    { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3 },
+    { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3|MASK_FSMULD },
     { "leon3v7",	MASK_ISA, MASK_LEON3 },
     { "sparclite",	MASK_ISA, MASK_SPARCLITE },
     /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
@@ -1421,34 +1423,35 @@  sparc_option_override (void)
     { "sparclet",	MASK_ISA, MASK_SPARCLET },
     /* TEMIC sparclet */
     { "tsc701",		MASK_ISA, MASK_SPARCLET },
-    { "v9",		MASK_ISA, MASK_V9 },
+    { "v9",		MASK_ISA, MASK_V9|MASK_FSMULD },
     /* UltraSPARC I, II, IIi */
     { "ultrasparc",	MASK_ISA,
     /* Although insns using %y are deprecated, it is a clear win.  */
-      MASK_V9|MASK_DEPRECATED_V8_INSNS },
+      MASK_V9|MASK_DEPRECATED_V8_INSNS|MASK_FSMULD },
     /* UltraSPARC III */
     /* ??? Check if %y issue still holds true.  */
     { "ultrasparc3",	MASK_ISA,
-      MASK_V9|MASK_DEPRECATED_V8_INSNS|MASK_VIS2 },
+      MASK_V9|MASK_DEPRECATED_V8_INSNS|MASK_VIS2|MASK_FSMULD },
     /* UltraSPARC T1 */
     { "niagara",	MASK_ISA,
-      MASK_V9|MASK_DEPRECATED_V8_INSNS },
+      MASK_V9|MASK_DEPRECATED_V8_INSNS|MASK_FSMULD },
     /* UltraSPARC T2 */
     { "niagara2",	MASK_ISA,
-      MASK_V9|MASK_POPC|MASK_VIS2 },
+      MASK_V9|MASK_POPC|MASK_VIS2|MASK_FSMULD },
     /* UltraSPARC T3 */
     { "niagara3",	MASK_ISA,
-      MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF },
+      MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF|MASK_FSMULD },
     /* UltraSPARC T4 */
     { "niagara4",	MASK_ISA,
-      MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF|MASK_CBCOND },
+      MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF|MASK_FSMULD|MASK_CBCOND },
     /* UltraSPARC M7 */
     { "niagara7",	MASK_ISA,
-      MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC },
+      MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_FSMULD|MASK_CBCOND
+      |MASK_SUBXC },
     /* UltraSPARC M8 */
     { "m8",		MASK_ISA,
-      MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC
-      |MASK_VIS4B }
+      MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_FSMULD|MASK_CBCOND
+      |MASK_SUBXC |MASK_VIS4B }
   };
   const struct cpu_table *cpu;
   unsigned int i;
@@ -1603,11 +1606,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 +1644,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..22267f50e90 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 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..e67cec52530 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,15 @@  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
+Floating-point Multiply Single to Double (FsMULd) instruction.  The default is
+@option{-mfsmuld} when targeting a CPU supporting the architecture versions V8
+or V9 with FPU except @option{-mcpu=leon}.
+
 @item -mpopc
 @itemx -mno-popc
 @opindex mpopc