diff mbox series

[51/52] sparc: New hook implementation sparc_c_mode_for_floating_type

Message ID 9966800639115aedb7524421aa5078663e3fe6fb.1717134752.git.linkw@linux.ibm.com
State New
Headers show
Series Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook | expand

Commit Message

Kewen.Lin June 3, 2024, 3:01 a.m. UTC
This is to add new port specific hook implementation
sparc_c_mode_for_floating_type, remove macros
{FLOAT,DOUBLE}_TYPE_SIZE defines and rename
LONG_DOUBLE_TYPE_SIZE to SPARC_LONG_DOUBLE_TYPE_SIZE
as we poison LONG_DOUBLE_TYPE_SIZE and some subtargets
still want to re-define it.

gcc/ChangeLog:

	* config/sparc/sparc.cc (sparc_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	(FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	(sparc_type_code): Replace FLOAT_TYPE_SIZE with TYPE_PRECISION of
	float_type_node.
	* config/sparc/sparc.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Remove.
	* config/sparc/freebsd.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/linux.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/linux64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/netbsd-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/openbsd64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/sol2.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/sp-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
	* config/sparc/sp64-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
---
 gcc/config/sparc/freebsd.h    |  4 ++--
 gcc/config/sparc/linux.h      |  2 +-
 gcc/config/sparc/linux64.h    |  4 ++--
 gcc/config/sparc/netbsd-elf.h | 12 ++++++------
 gcc/config/sparc/openbsd64.h  |  4 ++--
 gcc/config/sparc/sol2.h       |  2 +-
 gcc/config/sparc/sp-elf.h     |  4 ++--
 gcc/config/sparc/sp64-elf.h   |  4 ++--
 gcc/config/sparc/sparc.cc     | 31 ++++++++++++++++++++-----------
 gcc/config/sparc/sparc.h      |  9 ++++-----
 10 files changed, 42 insertions(+), 34 deletions(-)

Comments

Eric Botcazou June 3, 2024, 9:02 a.m. UTC | #1
> 	* config/sparc/sparc.cc (sparc_c_mode_for_floating_type): New
> 	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
> 	(FLOAT_TYPE_SIZE): Remove.
> 	(DOUBLE_TYPE_SIZE): Likewise.
> 	(LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	(sparc_type_code): Replace FLOAT_TYPE_SIZE with TYPE_PRECISION of
> 	float_type_node.
> 	* config/sparc/sparc.h (FLOAT_TYPE_SIZE): Remove.
> 	(DOUBLE_TYPE_SIZE): Remove.
> 	* config/sparc/freebsd.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/linux.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/linux64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/netbsd-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/openbsd64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/sol2.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/sp-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 	* config/sparc/sp64-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.

OK, modulo the following tweaks:

> --- a/gcc/config/sparc/sparc.cc
> +++ b/gcc/config/sparc/sparc.cc
> @@ -718,6 +718,7 @@ static bool sparc_vectorize_vec_perm_const
> (machine_mode, machine_mode, const vec_perm_indices &);
>  static bool sparc_can_follow_jump (const rtx_insn *, const rtx_insn *);
>  static HARD_REG_SET sparc_zero_call_used_regs (HARD_REG_SET);
> +static machine_mode sparc_c_mode_for_floating_type (enum tree_index);
>  
>  #ifdef SUBTARGET_ATTRIBUTE_TABLE
>  /* Table of valid machine attributes.  */
> @@ -971,6 +972,9 @@ char sparc_hard_reg_printed[8];
>  #undef TARGET_ZERO_CALL_USED_REGS
>  #define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
> 
> +#undef TARGET_C_MODE_FOR_FLOATING_TYPE
> +#define TARGET_C_MODE_FOR_FLOATING_TYPE sparc_c_mode_for_floating_type
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
> 
>  /* Return the memory reference contained in X if any, zero otherwise.  */
> @@ -9824,16 +9828,9 @@ sparc_assemble_integer (rtx x, unsigned int size, int
> aligned_p) #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
>  #endif
> 
> -#ifndef FLOAT_TYPE_SIZE
> -#define FLOAT_TYPE_SIZE BITS_PER_WORD
> -#endif
> -
> -#ifndef DOUBLE_TYPE_SIZE
> -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
> -#endif
> -
> -#ifndef LONG_DOUBLE_TYPE_SIZE
> -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
> +/* LONG_DOUBLE_TYPE_SIZE get poisoned, so add SPARC_ prefix.  */
> +#ifndef SPARC_LONG_LONG_TYPE_SIZE
> +#define SPARC_LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
>  #endif
> 
>  unsigned long

You can delete {SPARC_}LONG_DOUBLE_TYPE_SIZE too.

> @@ -9920,7 +9917,7 @@ sparc_type_code (tree type)
>  	  /* Carefully distinguish all the standard types of C,
>  	     without messing up if the language is not C.  */
> 
> -	  if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)
> +	  if (TYPE_PRECISION (type) == TYPE_PRECISION (float_type_node))
>  	    return (qualifiers | 6);
> 
>  	  else
> @@ -13984,4 +13981,16 @@ sparc_zero_call_used_regs (HARD_REG_SET
> need_zeroed_hardregs) return need_zeroed_hardregs;
>  }
> 
> +/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
> +   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
> +   default one for the others.  */
> +
> +static machine_mode
> +sparc_c_mode_for_floating_type (enum tree_index ti)
> +{
> +  if (ti == TI_LONG_DOUBLE_TYPE)
> +    return SPARC_LONG_DOUBLE_TYPE_SIZE == 128 ? TFmode : DFmode;
> +  return default_mode_for_floating_type (ti);
> +}
> +
>  #include "gt-sparc.h"

I think that TI_LONG_DOUBLE_TYPE is self-explanatory so just:

/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
   for TI_LONG_DOUBLE_TYPE and the default for others.
Kewen.Lin June 3, 2024, 9:37 a.m. UTC | #2
Hi Eric,

on 2024/6/3 17:02, Eric Botcazou wrote:
>> 	* config/sparc/sparc.cc (sparc_c_mode_for_floating_type): New
>> 	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
>> 	(FLOAT_TYPE_SIZE): Remove.
>> 	(DOUBLE_TYPE_SIZE): Likewise.
>> 	(LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	(sparc_type_code): Replace FLOAT_TYPE_SIZE with TYPE_PRECISION of
>> 	float_type_node.
>> 	* config/sparc/sparc.h (FLOAT_TYPE_SIZE): Remove.
>> 	(DOUBLE_TYPE_SIZE): Remove.
>> 	* config/sparc/freebsd.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/linux.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/linux64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/netbsd-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/openbsd64.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/sol2.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/sp-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
>> 	* config/sparc/sp64-elf.h (LONG_DOUBLE_TYPE_SIZE): Rename to ...
>> 	(SPARC_LONG_DOUBLE_TYPE_SIZE): ... this.
> 
> OK, modulo the following tweaks:

Thanks for the review!

> 
>> --- a/gcc/config/sparc/sparc.cc
>> +++ b/gcc/config/sparc/sparc.cc
>> @@ -718,6 +718,7 @@ static bool sparc_vectorize_vec_perm_const
>> (machine_mode, machine_mode, const vec_perm_indices &);
>>  static bool sparc_can_follow_jump (const rtx_insn *, const rtx_insn *);
>>  static HARD_REG_SET sparc_zero_call_used_regs (HARD_REG_SET);
>> +static machine_mode sparc_c_mode_for_floating_type (enum tree_index);
>>  
>>  #ifdef SUBTARGET_ATTRIBUTE_TABLE
>>  /* Table of valid machine attributes.  */
>> @@ -971,6 +972,9 @@ char sparc_hard_reg_printed[8];
>>  #undef TARGET_ZERO_CALL_USED_REGS
>>  #define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
>>
>> +#undef TARGET_C_MODE_FOR_FLOATING_TYPE
>> +#define TARGET_C_MODE_FOR_FLOATING_TYPE sparc_c_mode_for_floating_type
>> +
>>  struct gcc_target targetm = TARGET_INITIALIZER;
>>
>>  /* Return the memory reference contained in X if any, zero otherwise.  */
>> @@ -9824,16 +9828,9 @@ sparc_assemble_integer (rtx x, unsigned int size, int
>> aligned_p) #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
>>  #endif
>>
>> -#ifndef FLOAT_TYPE_SIZE
>> -#define FLOAT_TYPE_SIZE BITS_PER_WORD
>> -#endif
>> -
>> -#ifndef DOUBLE_TYPE_SIZE
>> -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
>> -#endif
>> -
>> -#ifndef LONG_DOUBLE_TYPE_SIZE
>> -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
>> +/* LONG_DOUBLE_TYPE_SIZE get poisoned, so add SPARC_ prefix.  */
>> +#ifndef SPARC_LONG_LONG_TYPE_SIZE
>> +#define SPARC_LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
>>  #endif
>>
>>  unsigned long
> 
> You can delete {SPARC_}LONG_DOUBLE_TYPE_SIZE too.

Good point, sparc.h already defines the default.

> 
>> @@ -9920,7 +9917,7 @@ sparc_type_code (tree type)
>>  	  /* Carefully distinguish all the standard types of C,
>>  	     without messing up if the language is not C.  */
>>
>> -	  if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)
>> +	  if (TYPE_PRECISION (type) == TYPE_PRECISION (float_type_node))
>>  	    return (qualifiers | 6);
>>
>>  	  else
>> @@ -13984,4 +13981,16 @@ sparc_zero_call_used_regs (HARD_REG_SET
>> need_zeroed_hardregs) return need_zeroed_hardregs;
>>  }
>>
>> +/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
>> +   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
>> +   default one for the others.  */
>> +
>> +static machine_mode
>> +sparc_c_mode_for_floating_type (enum tree_index ti)
>> +{
>> +  if (ti == TI_LONG_DOUBLE_TYPE)
>> +    return SPARC_LONG_DOUBLE_TYPE_SIZE == 128 ? TFmode : DFmode;
>> +  return default_mode_for_floating_type (ti);
>> +}
>> +
>>  #include "gt-sparc.h"
> 
> I think that TI_LONG_DOUBLE_TYPE is self-explanatory so just:
> 
> /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
>    for TI_LONG_DOUBLE_TYPE and the default for others.
> 

Will adjust it, thanks!

BR,
Kewen
diff mbox series

Patch

diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
index 3f00a083c1d..5396b32c405 100644
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -68,8 +68,8 @@  along with GCC; see the file COPYING3.  If not see
 
 /* Define for support of TFmode long double.
    SPARC ABI says that long double is 4 words.  */
-#undef  LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+#undef  SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
 
 /* Definitions for 64-bit SPARC running systems with ELF. */
 
diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h
index 9646fa9c41e..8cc53899193 100644
--- a/gcc/config/sparc/linux.h
+++ b/gcc/config/sparc/linux.h
@@ -115,7 +115,7 @@  do {									\
 
 /* Define for support of TFmode long double.
    SPARC ABI says that long double is 4 words.  */
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+#define SPARC_LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
 
 #undef DITF_CONVERSION_LIBFUNCS
 #define DITF_CONVERSION_LIBFUNCS 1
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index 1e2e4aef2ad..66426d8f5fe 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -61,8 +61,8 @@  along with GCC; see the file COPYING3.  If not see
 
 /* Define for support of TFmode long double.
    SPARC ABI says that long double is 4 words.  */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
 
 #undef CPP_SUBTARGET_SPEC
 #define CPP_SUBTARGET_SPEC "\
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
index 2cf85dd7096..3bb05c55278 100644
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -160,8 +160,8 @@  along with GCC; see the file COPYING3.  If not see
 
 #ifdef SPARC_BI_ARCH
 
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
 
 #undef  CC1_SPEC
 #if DEFAULT_ARCH32_P
@@ -181,8 +181,8 @@  along with GCC; see the file COPYING3.  If not see
 #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
  || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
 
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 128
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 128
 
 #undef  CC1_SPEC
 #define CC1_SPEC CC1_SPEC64
@@ -193,8 +193,8 @@  along with GCC; see the file COPYING3.  If not see
 /* A 32-bit only compiler.  NetBSD don't support 128 bit `long double'
    for 32-bit code, unlike Solaris.  */
 
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 64
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 64
 
 #undef  CC1_SPEC
 #define CC1_SPEC CC1_SPEC32
diff --git a/gcc/config/sparc/openbsd64.h b/gcc/config/sparc/openbsd64.h
index 9cd23f29b35..19cc20e69cd 100644
--- a/gcc/config/sparc/openbsd64.h
+++ b/gcc/config/sparc/openbsd64.h
@@ -54,8 +54,8 @@  along with GCC; see the file COPYING3.  If not see
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
 
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 128
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 128
 
 #undef LINK_SPEC
 #define LINK_SPEC \
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 552f58b2cc8..5de312551a5 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -437,7 +437,7 @@  extern const char *host_detect_local_cpu (int argc, const char **argv);
 
 /* Define for support of TFmode long double.
    SPARC ABI says that long double is 4 words.  */
-#define LONG_DOUBLE_TYPE_SIZE 128
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 128
 
 /* Solaris's _Qp_* library routine implementation clobbers the output
    memory before the inputs are fully consumed.  */
diff --git a/gcc/config/sparc/sp-elf.h b/gcc/config/sparc/sp-elf.h
index aa7982a9141..cc64d5dd58e 100644
--- a/gcc/config/sparc/sp-elf.h
+++ b/gcc/config/sparc/sp-elf.h
@@ -63,5 +63,5 @@  along with GCC; see the file COPYING3.  If not see
 #define WCHAR_TYPE_SIZE BITS_PER_WORD
 
 /* ??? until fixed.  */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 64
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 64
diff --git a/gcc/config/sparc/sp64-elf.h b/gcc/config/sparc/sp64-elf.h
index a9c53cb6d4f..6eb5b86ddce 100644
--- a/gcc/config/sparc/sp64-elf.h
+++ b/gcc/config/sparc/sp64-elf.h
@@ -69,5 +69,5 @@  along with GCC; see the file COPYING3.  If not see
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 16
 
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE 128
+#undef SPARC_LONG_DOUBLE_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE 128
diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 8a5f76c8885..6cecdd8e065 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -718,6 +718,7 @@  static bool sparc_vectorize_vec_perm_const (machine_mode, machine_mode,
 					    const vec_perm_indices &);
 static bool sparc_can_follow_jump (const rtx_insn *, const rtx_insn *);
 static HARD_REG_SET sparc_zero_call_used_regs (HARD_REG_SET);
+static machine_mode sparc_c_mode_for_floating_type (enum tree_index);
 
 #ifdef SUBTARGET_ATTRIBUTE_TABLE
 /* Table of valid machine attributes.  */
@@ -971,6 +972,9 @@  char sparc_hard_reg_printed[8];
 #undef TARGET_ZERO_CALL_USED_REGS
 #define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE sparc_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Return the memory reference contained in X if any, zero otherwise.  */
@@ -9824,16 +9828,9 @@  sparc_assemble_integer (rtx x, unsigned int size, int aligned_p)
 #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
 #endif
 
-#ifndef FLOAT_TYPE_SIZE
-#define FLOAT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef DOUBLE_TYPE_SIZE
-#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
-#ifndef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
+/* LONG_DOUBLE_TYPE_SIZE get poisoned, so add SPARC_ prefix.  */
+#ifndef SPARC_LONG_LONG_TYPE_SIZE
+#define SPARC_LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
 #endif
 
 unsigned long
@@ -9920,7 +9917,7 @@  sparc_type_code (tree type)
 	  /* Carefully distinguish all the standard types of C,
 	     without messing up if the language is not C.  */
 
-	  if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)
+	  if (TYPE_PRECISION (type) == TYPE_PRECISION (float_type_node))
 	    return (qualifiers | 6);
 
 	  else
@@ -13984,4 +13981,16 @@  sparc_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
   return need_zeroed_hardregs;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+sparc_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return SPARC_LONG_DOUBLE_TYPE_SIZE == 128 ? TFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 #include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 232ecb30ddc..8612832a03e 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -489,12 +489,11 @@  along with GCC; see the file COPYING3.  If not see
 #define INT_TYPE_SIZE		32
 #define LONG_TYPE_SIZE		(TARGET_ARCH64 ? 64 : 32)
 #define LONG_LONG_TYPE_SIZE	64
-#define FLOAT_TYPE_SIZE		32
-#define DOUBLE_TYPE_SIZE	64
 
-/* LONG_DOUBLE_TYPE_SIZE is defined per OS even though the
-   SPARC ABI says that it is 128-bit wide.  */
-/* #define LONG_DOUBLE_TYPE_SIZE	128 */
+/* SPARC_LONG_DOUBLE_TYPE_SIZE is defined per OS even though the
+   SPARC ABI says that it is 128-bit wide.  LONG_DOUBLE_TYPE_SIZE
+   get poisoned, so add SPARC_ prefix.  */
+/* #define SPARC_LONG_DOUBLE_TYPE_SIZE	128 */
 
 /* The widest floating-point format really supported by the hardware.  */
 #define WIDEST_HARDWARE_FP_SIZE 64