This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Remove LIBGCC2_HAS_?F_MODE target macros
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>
- Date: Fri, 12 Sep 2014 10:13:50 +0200
- Subject: Re: Remove LIBGCC2_HAS_?F_MODE target macros
- Authentication-results: sourceware.org; auth=none
- References: <Pine dot LNX dot 4 dot 64 dot 1409120121460 dot 5583 at digraph dot polyomino dot org dot uk>
On Fri, Sep 12, 2014 at 3:22 AM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch removes the LIBGCC2_HAS_{SF,DF,XF,TF}_MODE target macros,
> replacing them by predefines with -fbuilding-libgcc, together with a
> target hook that can influence those predefines when needed.
>
> The new default is that a floating-point mode is supported in libgcc
> if (a) it passes the scalar_mode_supported_p hook (otherwise it's not
> plausible for it to be supported in libgcc) and (b) it's one of those
> four modes (since those are the modes for which libgcc hardcodes the
> possibility of support). The target hook can override the default
> choice (in either direction) for modes that pass
> scalar_mode_supported_p (although overriding in the direction of
> returning true when the default would return false only makes sense if
> all relevant functions are specially defined in libgcc for that
> particular target).
>
> The previous default settings depended on various settings such as
> LIBGCC2_LONG_DOUBLE_TYPE_SIZE, as well as targets defining the above
> target macros if the default wasn't correct.
>
> The default scalar_mode_supported_p only declares a floating-point
> mode to be supported if it matches one of float / double / long
> double. This means that in most cases where a mode is only supported
> conditionally in libgcc (TFmode only supported if it's the mode of
> long double, most commonly), the default gets things right. Overrides
> were needed in the following cases:
>
> * SFmode would always have been supported in libgcc (the condition was
> BITS_PER_UNIT == 8, true for all current targets), but pdp11
> defaults to 64-bit float, and in that case SFmode would fail
> scalar_mode_supported_p. I don't know if libgcc actually built for
> pdp11 (and the port may well no longer be being used), but this
> patch adds a scalar_mode_supported_p hook to it to ensure SFmode is
> treated as supported.
>
> * Certain i386 and ia64 targets need the new hook to match the
> existing cases for when XFmode or TFmode support is present in
> libgcc. For i386, the hook can always declare XFmode to be
> supported - the cases where it's not are the cases where long double
> is TFmode, in which case XFmode fails scalar_mode_supported_p[*] -
> but TFmode support needs to be conditional. (And of the targets not
> defining LIBGCC2_HAS_TF_MODE before this patch, some defined
> LONG_DOUBLE_TYPE_SIZE to 64, so ensuring LIBGCC2_HAS_TF_MODE would
> always be false, while others did not define it, so allowing it to
> be true in the -mlong-double-128 case. This patch matches that
> logic, although I suspect all the latter targets would have been
> broken if you tried to enable -mlong-double-128 by default, for lack
> of the soft-fp TFmode support in libgcc, which is separately
> configured.)
>
> [*] I don't know if it's deliberate not to support __float80 at all
> with -mlong-double-128.
>
> In order to implement the default version of the new hook,
> insn-modes.h was made to contain macros such as HAVE_TFmode for each
> machine mode, so the default hook can contain conditionals on whether
> XFmode and TFmode exist (to match the hardcoding of a list of modes in
> libgcc). This is also used in fortran/trans-types.c; previously it
> had a conditional on defined(LIBGCC2_HAS_TF_MODE) (a bit dubious,
> since it ignored the value of the macro), which is replaced by testing
> defined(HAVE_TFmode), in conjunction with requiring
> targetm.libgcc_floating_mode_supported_p.
>
> (Fortran is testing something stronger than that hook: not only is
> libgcc support required, but also libm or equivalent. Thus, it has a
> test for ENABLE_LIBQUADMATH_SUPPORT in the case that the mode is
> TFmode and that's not the same as any of the three standard types.
> The old and new tests are intended to accept exactly the same set of
> modes for all targets.)
>
> Apart from the four target macros eliminated by this patch, it gets us
> closer to eliminating LIBGCC2_LONG_DOUBLE_TYPE_SIZE as well, though a
> few more places using that macro need changing first.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu; also
> built cc1 for crosses to ia64-elf and pdp11-none as a minimal test of
> changes for those targets. OK to commit?
Ok.
Thanks,
Richard.
> gcc:
> 2014-09-11 Joseph Myers <joseph@codesourcery.com>
>
> * target.def (libgcc_floating_mode_supported_p): New hook.
> * targhooks.c (default_libgcc_floating_mode_supported_p): New
> function.
> * targhooks.h (default_libgcc_floating_mode_supported_p): Declare.
> * doc/tm.texi.in (LIBGCC2_HAS_DF_MODE, LIBGCC2_HAS_XF_MODE)
> (LIBGCC2_HAS_TF_MODE): Remove.
> (TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P): New @hook.
> * doc/tm.texi: Regenerate.
> * genmodes.c (emit_insn_modes_h): Define HAVE_%smode for each
> machine mode.
> * system.h (LIBGCC2_HAS_SF_MODE, LIBGCC2_HAS_DF_MODE)
> (LIBGCC2_HAS_XF_MODE, LIBGCC2_HAS_TF_MODE): Poison.
> * config/i386/cygming.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/darwin.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/djgpp.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/dragonfly.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/freebsd.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/gnu-user-common.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/i386-interix.h (IX86_NO_LIBGCC_TFMODE): Define.
> * config/i386/i386.c (ix86_libgcc_floating_mode_supported_p): New
> function.
> (TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P): Define.
> * config/i386/i386elf.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/lynx.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/netbsd-elf.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/netbsd64.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/nto.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/openbsd.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/i386/openbsdelf.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/rtemself.h (IX86_NO_LIBGCC_TFMODE): Define.
> * config/i386/sol2.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/i386/vx-common.h (IX86_MAYBE_NO_LIBGCC_TFMODE): Define.
> * config/ia64/elf.h (IA64_NO_LIBGCC_TFMODE): Define.
> * config/ia64/freebsd.h (IA64_NO_LIBGCC_TFMODE): Define.
> * config/ia64/hpux.h (LIBGCC2_HAS_XF_MODE, LIBGCC2_HAS_TF_MODE):
> Remove.
> * config/ia64/ia64.c (TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P):
> New macro.
> (ia64_libgcc_floating_mode_supported_p): New function.
> * config/ia64/linux.h (LIBGCC2_HAS_TF_MODE): Remove.
> * config/ia64/vms.h (IA64_NO_LIBGCC_XFMODE)
> (IA64_NO_LIBGCC_TFMODE): Define.
> * config/msp430/msp430.h (LIBGCC2_HAS_DF_MODE): Remove.
> * config/pdp11/pdp11.c (TARGET_SCALAR_MODE_SUPPORTED_P): New
> macro.
> (pdp11_scalar_mode_supported_p): New function.
> * config/rl78/rl78.h (LIBGCC2_HAS_DF_MODE): Remove.
> * config/rx/rx.h (LIBGCC2_HAS_DF_MODE): Remove.
>
>
> gcc/c-family:
> 2014-09-11 Joseph Myers <joseph@codesourcery.com>
>
> * c-cppbuiltin.c (c_cpp_builtins): Define __LIBGCC_HAS_%s_MODE__
> macros for floating-point modes.
>
> gcc/fortran:
> 2014-09-11 Joseph Myers <joseph@codesourcery.com>
>
> * trans-types.c (gfc_init_kinds): Check
> targetm.libgcc_floating_mode_supported_p for floating-point
> modes. Check HAVE_TFmode instead of LIBGCC2_HAS_TF_MODE.
>
> libgcc:
> 2014-09-11 Joseph Myers <joseph@codesourcery.com>
>
> * libgcc2.h (LIBGCC2_HAS_SF_MODE): Define using
> __LIBGCC_HAS_SF_MODE__.
> (LIBGCC2_HAS_DF_MODE): Define using __LIBGCC_HAS_DF_MODE__.
> (LIBGCC2_HAS_XF_MODE): Define using __LIBGCC_HAS_XF_MODE__.
> (LIBGCC2_HAS_TF_MODE): Define using __LIBGCC_HAS_TF_MODE__.
> * config/libbid/bid_gcc_intrinsics.h
> (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Do not define.
> (LIBGCC2_HAS_XF_MODE): Define using __LIBGCC_HAS_XF_MODE__.
> (LIBGCC2_HAS_TF_MODE): Define using __LIBGCC_HAS_TF_MODE__.
> * fixed-bit.h (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Do not define.
> (LIBGCC2_HAS_SF_MODE): Define using __LIBGCC_HAS_SF_MODE__.
> (LIBGCC2_HAS_DF_MODE): Define using __LIBGCC_HAS_DF_MODE__.
>
> Index: gcc/c-family/c-cppbuiltin.c
> ===================================================================
> --- gcc/c-family/c-cppbuiltin.c (revision 215170)
> +++ gcc/c-family/c-cppbuiltin.c (working copy)
> @@ -956,6 +956,13 @@ c_cpp_builtins (cpp_reader *pfile)
> sprintf (macro_name, "__LIBGCC_%s_MANT_DIG__", name);
> builtin_define_with_int_value (macro_name,
> REAL_MODE_FORMAT (mode)->p);
> + if (!targetm.scalar_mode_supported_p (mode)
> + || !targetm.libgcc_floating_mode_supported_p (mode))
> + continue;
> + macro_name = (char *) alloca (strlen (name)
> + + sizeof ("__LIBGCC_HAS__MODE__"));
> + sprintf (macro_name, "__LIBGCC_HAS_%s_MODE__", name);
> + cpp_define (pfile, macro_name);
> }
>
> /* For libgcc crtstuff.c and libgcc2.c. */
> Index: gcc/config/i386/cygming.h
> ===================================================================
> --- gcc/config/i386/cygming.h (revision 215170)
> +++ gcc/config/i386/cygming.h (working copy)
> @@ -340,8 +340,6 @@ do { \
> asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
>
> /* Output function declarations at the end of the file. */
> Index: gcc/config/i386/darwin.h
> ===================================================================
> --- gcc/config/i386/darwin.h (revision 215170)
> +++ gcc/config/i386/darwin.h (working copy)
> @@ -154,8 +154,6 @@ extern int darwin_emit_branch_islands;
> #define SHIFT_DOUBLE_OMITS_COUNT 0
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
>
> #undef TARGET_ASM_FILE_END
> Index: gcc/config/i386/djgpp.h
> ===================================================================
> --- gcc/config/i386/djgpp.h (revision 215170)
> +++ gcc/config/i386/djgpp.h (working copy)
> @@ -177,3 +177,5 @@ while (0)
> /* Support for C++ templates. */
> #undef MAKE_DECL_ONE_ONLY
> #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/dragonfly.h
> ===================================================================
> --- gcc/config/i386/dragonfly.h (revision 215170)
> +++ gcc/config/i386/dragonfly.h (working copy)
> @@ -90,8 +90,6 @@ see the files COPYING3 and COPYING.RUNTIME respect
> #define TARGET_96_ROUND_53_LONG_DOUBLE (!TARGET_64BIT)
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
>
> /* Static stack checking is supported by means of probes. */
> Index: gcc/config/i386/freebsd.h
> ===================================================================
> --- gcc/config/i386/freebsd.h (revision 215170)
> +++ gcc/config/i386/freebsd.h (working copy)
> @@ -132,8 +132,6 @@ along with GCC; see the file COPYING3. If not see
> #define TARGET_96_ROUND_53_LONG_DOUBLE (!TARGET_64BIT)
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
>
> /* Static stack checking is supported by means of probes. */
> Index: gcc/config/i386/gnu-user-common.h
> ===================================================================
> --- gcc/config/i386/gnu-user-common.h (revision 215170)
> +++ gcc/config/i386/gnu-user-common.h (working copy)
> @@ -58,8 +58,6 @@ along with GCC; see the file COPYING3. If not see
> GNU_USER_TARGET_ENDFILE_SPEC
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
>
> #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
> Index: gcc/config/i386/i386-interix.h
> ===================================================================
> --- gcc/config/i386/i386-interix.h (revision 215170)
> +++ gcc/config/i386/i386-interix.h (working copy)
> @@ -143,6 +143,8 @@ do { \
> #undef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
>
> +#define IX86_NO_LIBGCC_TFMODE
> +
> #undef TARGET_LIBC_HAS_FUNCTION
> #define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
>
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c (revision 215170)
> +++ gcc/config/i386/i386.c (working copy)
> @@ -41217,6 +41217,31 @@ ix86_vector_mode_supported_p (enum machine_mode mo
> return false;
> }
>
> +/* Implement target hook libgcc_floating_mode_supported_p. */
> +static bool
> +ix86_libgcc_floating_mode_supported_p (enum machine_mode mode)
> +{
> + switch (mode)
> + {
> + case SFmode:
> + case DFmode:
> + case XFmode:
> + return true;
> +
> + case TFmode:
> +#ifdef IX86_NO_LIBGCC_TFMODE
> + return false;
> +#elif defined IX86_MAYBE_NO_LIBGCC_TFMODE
> + return TARGET_LONG_DOUBLE_128;
> +#else
> + return true;
> +#endif
> +
> + default:
> + return false;
> + }
> +}
> +
> /* Target hook for c_mode_for_suffix. */
> static enum machine_mode
> ix86_c_mode_for_suffix (char suffix)
> @@ -47282,6 +47307,10 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *
> #undef TARGET_VECTOR_MODE_SUPPORTED_P
> #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
>
> +#undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
> +#define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
> + ix86_libgcc_floating_mode_supported_p
> +
> #undef TARGET_C_MODE_FOR_SUFFIX
> #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
>
> Index: gcc/config/i386/i386elf.h
> ===================================================================
> --- gcc/config/i386/i386elf.h (revision 215170)
> +++ gcc/config/i386/i386elf.h (working copy)
> @@ -101,3 +101,5 @@ along with GCC; see the file COPYING3. If not see
> #undef ASM_OUTPUT_ALIGNED_BSS
> #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
> asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/lynx.h
> ===================================================================
> --- gcc/config/i386/lynx.h (revision 215170)
> +++ gcc/config/i386/lynx.h (working copy)
> @@ -85,3 +85,5 @@ along with GCC; see the file COPYING3. If not see
> TLS is detected by configure. We undefine it here. */
>
> #undef HAVE_AS_TLS
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/netbsd-elf.h
> ===================================================================
> --- gcc/config/i386/netbsd-elf.h (revision 215170)
> +++ gcc/config/i386/netbsd-elf.h (working copy)
> @@ -119,3 +119,5 @@ along with GCC; see the file COPYING3. If not see
> #define DEFAULT_PCC_STRUCT_RETURN 1
>
> #define HAVE_ENABLE_EXECUTE_STACK
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/netbsd64.h
> ===================================================================
> --- gcc/config/i386/netbsd64.h (revision 215170)
> +++ gcc/config/i386/netbsd64.h (working copy)
> @@ -67,3 +67,5 @@ along with GCC; see the file COPYING3. If not see
> }
>
> #define HAVE_ENABLE_EXECUTE_STACK
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/nto.h
> ===================================================================
> --- gcc/config/i386/nto.h (revision 215170)
> +++ gcc/config/i386/nto.h (working copy)
> @@ -103,3 +103,5 @@ crti.o%s \
> #define TARGET_POSIX_IO
>
> #undef DBX_REGISTER_NUMBER
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/openbsd.h
> ===================================================================
> --- gcc/config/i386/openbsd.h (revision 215170)
> +++ gcc/config/i386/openbsd.h (working copy)
> @@ -99,3 +99,5 @@ along with GCC; see the file COPYING3. If not see
> #undef ASM_QUAD
>
> #define TARGET_HAVE_NAMED_SECTIONS false
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/openbsdelf.h
> ===================================================================
> --- gcc/config/i386/openbsdelf.h (revision 215170)
> +++ gcc/config/i386/openbsdelf.h (working copy)
> @@ -113,6 +113,4 @@ along with GCC; see the file COPYING3. If not see
> #define HAVE_ENABLE_EXECUTE_STACK
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
> Index: gcc/config/i386/rtemself.h
> ===================================================================
> --- gcc/config/i386/rtemself.h (revision 215170)
> +++ gcc/config/i386/rtemself.h (working copy)
> @@ -38,3 +38,5 @@ along with GCC; see the file COPYING3. If not see
> #else
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
> #endif
> +
> +#define IX86_NO_LIBGCC_TFMODE
> Index: gcc/config/i386/sol2.h
> ===================================================================
> --- gcc/config/i386/sol2.h (revision 215170)
> +++ gcc/config/i386/sol2.h (working copy)
> @@ -238,6 +238,4 @@ along with GCC; see the file COPYING3. If not see
> #endif
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #define LIBGCC2_TF_CEXT q
> Index: gcc/config/i386/vx-common.h
> ===================================================================
> --- gcc/config/i386/vx-common.h (revision 215170)
> +++ gcc/config/i386/vx-common.h (working copy)
> @@ -31,3 +31,5 @@ along with GCC; see the file COPYING3. If not see
>
> #undef DBX_REGISTER_NUMBER
> #define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
> +
> +#define IX86_MAYBE_NO_LIBGCC_TFMODE
> Index: gcc/config/ia64/elf.h
> ===================================================================
> --- gcc/config/ia64/elf.h (revision 215170)
> +++ gcc/config/ia64/elf.h (working copy)
> @@ -65,4 +65,6 @@ see the files COPYING3 and COPYING.RUNTIME respect
> %{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}\
> crti.o%s crtbegin.o%s"
>
> +#define IA64_NO_LIBGCC_TFMODE
> +
> /* End of elf.h */
> Index: gcc/config/ia64/freebsd.h
> ===================================================================
> --- gcc/config/ia64/freebsd.h (revision 215170)
> +++ gcc/config/ia64/freebsd.h (working copy)
> @@ -50,3 +50,5 @@ along with GCC; see the file COPYING3. If not see
> #define TARGET_ELF 1
>
> #define JMP_BUF_SIZE 76
> +
> +#define IA64_NO_LIBGCC_TFMODE
> Index: gcc/config/ia64/hpux.h
> ===================================================================
> --- gcc/config/ia64/hpux.h (revision 215170)
> +++ gcc/config/ia64/hpux.h (working copy)
> @@ -189,14 +189,6 @@ do { \
>
> #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
>
> -/* Put all *xf routines in libgcc, regardless of long double size. */
> -#undef LIBGCC2_HAS_XF_MODE
> -#define LIBGCC2_HAS_XF_MODE 1
> -
> -/* Put all *tf routines in libgcc, regardless of long double size. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> -
> /* HP-UX headers are C++-compatible. */
> #define NO_IMPLICIT_EXTERN_C
>
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> --- gcc/config/ia64/ia64.c (revision 215170)
> +++ gcc/config/ia64/ia64.c (working copy)
> @@ -319,6 +319,7 @@ static rtx ia64_struct_value_rtx (tree, int);
> static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
> static bool ia64_scalar_mode_supported_p (enum machine_mode mode);
> static bool ia64_vector_mode_supported_p (enum machine_mode mode);
> +static bool ia64_libgcc_floating_mode_supported_p (enum machine_mode mode);
> static bool ia64_legitimate_constant_p (enum machine_mode, rtx);
> static bool ia64_legitimate_address_p (enum machine_mode, rtx, bool);
> static bool ia64_cannot_force_const_mem (enum machine_mode, rtx);
> @@ -598,6 +599,10 @@ static const struct attribute_spec ia64_attribute_
> #undef TARGET_VECTOR_MODE_SUPPORTED_P
> #define TARGET_VECTOR_MODE_SUPPORTED_P ia64_vector_mode_supported_p
>
> +#undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
> +#define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
> + ia64_libgcc_floating_mode_supported_p
> +
> /* ia64 architecture manual 4.4.7: ... reads, writes, and flushes may occur
> in an order different from the specified program order. */
> #undef TARGET_RELAXED_ORDERING
> @@ -10939,6 +10944,36 @@ ia64_vector_mode_supported_p (enum machine_mode mo
> }
> }
>
> +/* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P. */
> +
> +static bool
> +ia64_libgcc_floating_mode_supported_p (enum machine_mode mode)
> +{
> + switch (mode)
> + {
> + case SFmode:
> + case DFmode:
> + return true;
> +
> + case XFmode:
> +#ifdef IA64_NO_LIBGCC_XFMODE
> + return false;
> +#else
> + return true;
> +#endif
> +
> + case TFmode:
> +#ifdef IA64_NO_LIBGCC_TFMODE
> + return false;
> +#else
> + return true;
> +#endif
> +
> + default:
> + return false;
> + }
> +}
> +
> /* Implement the FUNCTION_PROFILER macro. */
>
> void
> Index: gcc/config/ia64/linux.h
> ===================================================================
> --- gcc/config/ia64/linux.h (revision 215170)
> +++ gcc/config/ia64/linux.h (working copy)
> @@ -77,8 +77,6 @@ do { \
> #define LINK_EH_SPEC ""
>
> /* Put all *tf routines in libgcc. */
> -#undef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE 1
> #undef LIBGCC2_TF_CEXT
> #define LIBGCC2_TF_CEXT q
>
> Index: gcc/config/ia64/vms.h
> ===================================================================
> --- gcc/config/ia64/vms.h (revision 215170)
> +++ gcc/config/ia64/vms.h (working copy)
> @@ -154,3 +154,6 @@ STATIC func_ptr __CTOR_LIST__[1]
> /* Default values for _CRTL_VER and _VMS_VER. */
> #define VMS_DEFAULT_CRTL_VER 80300000
> #define VMS_DEFAULT_VMS_VER 80300000
> +
> +#define IA64_NO_LIBGCC_XFMODE
> +#define IA64_NO_LIBGCC_TFMODE
> Index: gcc/config/msp430/msp430.h
> ===================================================================
> --- gcc/config/msp430/msp430.h (revision 215170)
> +++ gcc/config/msp430/msp430.h (working copy)
> @@ -112,7 +112,6 @@ extern bool msp430x;
> #define DOUBLE_TYPE_SIZE 64
> #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/
>
> -#define LIBGCC2_HAS_DF_MODE 1
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
>
> #define DEFAULT_SIGNED_CHAR 0
> Index: gcc/config/pdp11/pdp11.c
> ===================================================================
> --- gcc/config/pdp11/pdp11.c (revision 215170)
> +++ gcc/config/pdp11/pdp11.c (working copy)
> @@ -157,6 +157,8 @@ static void pdp11_function_arg_advance (cumulative
> enum machine_mode, const_tree, bool);
> static void pdp11_conditional_register_usage (void);
> static bool pdp11_legitimate_constant_p (enum machine_mode, rtx);
> +
> +static bool pdp11_scalar_mode_supported_p (enum machine_mode);
>
> /* Initialize the GCC target structure. */
> #undef TARGET_ASM_BYTE_OP
> @@ -223,6 +225,9 @@ static bool pdp11_legitimate_constant_p (enum mach
>
> #undef TARGET_LEGITIMATE_CONSTANT_P
> #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
> +
> +#undef TARGET_SCALAR_MODE_SUPPORTED_P
> +#define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p
>
> /* A helper function to determine if REGNO should be saved in the
> current function's stack frame. */
> @@ -1901,4 +1906,15 @@ pdp11_legitimate_constant_p (enum machine_mode mod
> return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
> }
>
> +/* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
> +
> +static bool
> +pdp11_scalar_mode_supported_p (enum machine_mode mode)
> +{
> + /* Support SFmode even with -mfloat64. */
> + if (mode == SFmode)
> + return true;
> + return default_scalar_mode_supported_p (mode);
> +}
> +
> struct gcc_target targetm = TARGET_INITIALIZER;
> Index: gcc/config/rl78/rl78.h
> ===================================================================
> --- gcc/config/rl78/rl78.h (revision 215170)
> +++ gcc/config/rl78/rl78.h (working copy)
> @@ -98,7 +98,6 @@
> #define DOUBLE_TYPE_SIZE 32 /*64*/
> #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/
>
> -#define LIBGCC2_HAS_DF_MODE 1
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
>
> #define DEFAULT_SIGNED_CHAR 0
> Index: gcc/config/rx/rx.h
> ===================================================================
> --- gcc/config/rx/rx.h (revision 215170)
> +++ gcc/config/rx/rx.h (working copy)
> @@ -131,10 +131,8 @@
> #define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
>
> #ifdef __RX_32BIT_DOUBLES__
> -#define LIBGCC2_HAS_DF_MODE 0
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 32
> #else
> -#define LIBGCC2_HAS_DF_MODE 1
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
> #endif
>
> Index: gcc/doc/tm.texi
> ===================================================================
> --- gcc/doc/tm.texi (revision 215170)
> +++ gcc/doc/tm.texi (working copy)
> @@ -1549,29 +1549,6 @@ if you want routines in @file{libgcc2.a} for a siz
> default is @code{LONG_DOUBLE_TYPE_SIZE}.
> @end defmac
>
> -@defmac LIBGCC2_HAS_DF_MODE
> -Define this macro if neither @code{DOUBLE_TYPE_SIZE} nor
> -@code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is
> -@code{DFmode} but you want @code{DFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and either @code{DOUBLE_TYPE_SIZE}
> -or @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is 64 then the default is 1,
> -otherwise it is 0.
> -@end defmac
> -
> -@defmac LIBGCC2_HAS_XF_MODE
> -Define this macro if @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is not
> -@code{XFmode} but you want @code{XFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE}
> -is 80 then the default is 1, otherwise it is 0.
> -@end defmac
> -
> -@defmac LIBGCC2_HAS_TF_MODE
> -Define this macro if @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is not
> -@code{TFmode} but you want @code{TFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE}
> -is 128 then the default is 1, otherwise it is 0.
> -@end defmac
> -
> @defmac LIBGCC2_GNU_PREFIX
> This macro corresponds to the @code{TARGET_LIBFUNC_GNU_PREFIX} target
> hook and should be defined if that hook is overriden to be true. It
> @@ -4226,6 +4203,14 @@ If this hook allows @code{val} to have a scalar mo
> @code{int8x8x3_t}s in registers rather than forcing them onto the stack.
> @end deftypefn
>
> +@deftypefn {Target Hook} bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P (enum machine_mode @var{mode})
> +Define this to return nonzero if libgcc provides support for the
> +floating-point mode @var{mode}, which is known to pass
> +@code{TARGET_SCALAR_MODE_SUPPORTED_P}. The default version of this
> +hook returns true for all of @code{SFmode}, @code{DFmode},
> +@code{XFmode} and @code{TFmode}, if such modes exist.
> +@end deftypefn
> +
> @deftypefn {Target Hook} bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (enum machine_mode @var{mode})
> Define this to return nonzero for machine modes for which the port has
> small register classes. If this target hook returns nonzero for a given
> Index: gcc/doc/tm.texi.in
> ===================================================================
> --- gcc/doc/tm.texi.in (revision 215170)
> +++ gcc/doc/tm.texi.in (working copy)
> @@ -1391,29 +1391,6 @@ if you want routines in @file{libgcc2.a} for a siz
> default is @code{LONG_DOUBLE_TYPE_SIZE}.
> @end defmac
>
> -@defmac LIBGCC2_HAS_DF_MODE
> -Define this macro if neither @code{DOUBLE_TYPE_SIZE} nor
> -@code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is
> -@code{DFmode} but you want @code{DFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and either @code{DOUBLE_TYPE_SIZE}
> -or @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is 64 then the default is 1,
> -otherwise it is 0.
> -@end defmac
> -
> -@defmac LIBGCC2_HAS_XF_MODE
> -Define this macro if @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is not
> -@code{XFmode} but you want @code{XFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE}
> -is 80 then the default is 1, otherwise it is 0.
> -@end defmac
> -
> -@defmac LIBGCC2_HAS_TF_MODE
> -Define this macro if @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE} is not
> -@code{TFmode} but you want @code{TFmode} routines in @file{libgcc2.a}
> -anyway. If you don't define this and @code{LIBGCC2_LONG_DOUBLE_TYPE_SIZE}
> -is 128 then the default is 1, otherwise it is 0.
> -@end defmac
> -
> @defmac LIBGCC2_GNU_PREFIX
> This macro corresponds to the @code{TARGET_LIBFUNC_GNU_PREFIX} target
> hook and should be defined if that hook is overriden to be true. It
> @@ -3530,6 +3507,8 @@ stack.
>
> @hook TARGET_ARRAY_MODE_SUPPORTED_P
>
> +@hook TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
> +
> @hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
>
> @hook TARGET_FLAGS_REGNUM
> Index: gcc/fortran/trans-types.c
> ===================================================================
> --- gcc/fortran/trans-types.c (revision 215170)
> +++ gcc/fortran/trans-types.c (working copy)
> @@ -31,8 +31,8 @@ along with GCC; see the file COPYING3. If not see
> BOOL_TYPE_SIZE, BITS_PER_UNIT, POINTER_SIZE,
> INT_TYPE_SIZE, CHAR_TYPE_SIZE, SHORT_TYPE_SIZE,
> LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE,
> - FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE,
> - LONG_DOUBLE_TYPE_SIZE and LIBGCC2_HAS_TF_MODE. */
> + FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE and
> + LONG_DOUBLE_TYPE_SIZE. */
> #include "tree.h"
> #include "stor-layout.h"
> #include "stringpool.h"
> @@ -427,10 +427,13 @@ gfc_init_kinds (void)
> /* Only let float, double, long double and __float128 go through.
> Runtime support for others is not provided, so they would be
> useless. */
> + if (!targetm.libgcc_floating_mode_supported_p ((enum machine_mode)
> + mode))
> + continue;
> if (mode != TYPE_MODE (float_type_node)
> && (mode != TYPE_MODE (double_type_node))
> && (mode != TYPE_MODE (long_double_type_node))
> -#if defined(LIBGCC2_HAS_TF_MODE) && defined(ENABLE_LIBQUADMATH_SUPPORT)
> +#if defined(HAVE_TFmode) && defined(ENABLE_LIBQUADMATH_SUPPORT)
> && (mode != TFmode)
> #endif
> )
> Index: gcc/genmodes.c
> ===================================================================
> --- gcc/genmodes.c (revision 215170)
> +++ gcc/genmodes.c (working copy)
> @@ -1029,6 +1029,7 @@ enum machine_mode\n{");
> int count_ = printf (" %smode,", m->name);
> printf ("%*s/* %s:%d */\n", 27 - count_, "",
> trim_filename (m->file), m->line);
> + printf ("#define HAVE_%smode\n", m->name);
> }
>
> puts (" MAX_MACHINE_MODE,\n");
> Index: gcc/system.h
> ===================================================================
> --- gcc/system.h (revision 215170)
> +++ gcc/system.h (working copy)
> @@ -846,7 +846,8 @@ extern void fancy_abort (const char *, int, const
> CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
> HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT \
> OUTPUT_ADDR_CONST_EXTRA SMALL_REGISTER_CLASSES ASM_OUTPUT_IDENT \
> - ASM_BYTE_OP MEMBER_TYPE_FORCES_BLK
> + ASM_BYTE_OP MEMBER_TYPE_FORCES_BLK LIBGCC2_HAS_SF_MODE \
> + LIBGCC2_HAS_DF_MODE LIBGCC2_HAS_XF_MODE LIBGCC2_HAS_TF_MODE
>
> /* Target macros only used for code built for the target, that have
> moved to libgcc-tm.h or have never been present elsewhere. */
> Index: gcc/target.def
> ===================================================================
> --- gcc/target.def (revision 215170)
> +++ gcc/target.def (working copy)
> @@ -2985,6 +2985,16 @@ If this hook allows @code{val} to have a scalar mo
> bool, (enum machine_mode mode, unsigned HOST_WIDE_INT nelems),
> hook_bool_mode_uhwi_false)
>
> +DEFHOOK
> +(libgcc_floating_mode_supported_p,
> + "Define this to return nonzero if libgcc provides support for the \n\
> +floating-point mode @var{mode}, which is known to pass \n\
> +@code{TARGET_SCALAR_MODE_SUPPORTED_P}. The default version of this \n\
> +hook returns true for all of @code{SFmode}, @code{DFmode}, \n\
> +@code{XFmode} and @code{TFmode}, if such modes exist.",
> + bool, (enum machine_mode mode),
> + default_libgcc_floating_mode_supported_p)
> +
> /* Compute cost of moving data from a register of class FROM to one of
> TO, using MODE. */
> DEFHOOK
> Index: gcc/targhooks.c
> ===================================================================
> --- gcc/targhooks.c (revision 215170)
> +++ gcc/targhooks.c (working copy)
> @@ -424,6 +424,33 @@ default_scalar_mode_supported_p (enum machine_mode
> }
> }
>
> +/* Return true if libgcc supports floating-point mode MODE (known to
> + be supported as a scalar mode). */
> +
> +bool
> +default_libgcc_floating_mode_supported_p (enum machine_mode mode)
> +{
> + switch (mode)
> + {
> +#ifdef HAVE_SFmode
> + case SFmode:
> +#endif
> +#ifdef HAVE_DFmode
> + case DFmode:
> +#endif
> +#ifdef HAVE_XFmode
> + case XFmode:
> +#endif
> +#ifdef HAVE_TFmode
> + case TFmode:
> +#endif
> + return true;
> +
> + default:
> + return false;
> + }
> +}
> +
> /* Make some target macros useable by target-independent code. */
> bool
> targhook_words_big_endian (void)
> Index: gcc/targhooks.h
> ===================================================================
> --- gcc/targhooks.h (revision 215170)
> +++ gcc/targhooks.h (working copy)
> @@ -67,6 +67,7 @@ extern bool default_print_operand_punct_valid_p (u
> extern tree default_mangle_assembler_name (const char *);
>
> extern bool default_scalar_mode_supported_p (enum machine_mode);
> +extern bool default_libgcc_floating_mode_supported_p (enum machine_mode);
> extern bool targhook_words_big_endian (void);
> extern bool targhook_float_words_big_endian (void);
> extern bool default_float_exceptions_rounding_supported_p (void);
> Index: libgcc/config/libbid/bid_gcc_intrinsics.h
> ===================================================================
> --- libgcc/config/libbid/bid_gcc_intrinsics.h (revision 215170)
> +++ libgcc/config/libbid/bid_gcc_intrinsics.h (working copy)
> @@ -31,20 +31,18 @@ see the files COPYING3 and COPYING.RUNTIME respect
> #include "tm.h"
> #include "libgcc_tm.h"
>
> -#ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
> -#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
> +#ifdef __LIBGCC_HAS_XF_MODE__
> +#define LIBGCC2_HAS_XF_MODE 1
> +#else
> +#define LIBGCC2_HAS_XF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_XF_MODE
> -#define LIBGCC2_HAS_XF_MODE \
> - (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
> +#ifdef __LIBGCC_HAS_TF_MODE__
> +#define LIBGCC2_HAS_TF_MODE 1
> +#else
> +#define LIBGCC2_HAS_TF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE \
> - (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
> -#endif
> -
> #ifndef BID_HAS_XF_MODE
> #define BID_HAS_XF_MODE LIBGCC2_HAS_XF_MODE
> #endif
> Index: libgcc/fixed-bit.h
> ===================================================================
> --- libgcc/fixed-bit.h (revision 215170)
> +++ libgcc/fixed-bit.h (working copy)
> @@ -45,21 +45,18 @@ see the files COPYING3 and COPYING.RUNTIME respect
> Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
> generated. */
>
> -#ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
> -#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
> +#ifdef __LIBGCC_HAS_SF_MODE__
> +#define LIBGCC2_HAS_SF_MODE 1
> +#else
> +#define LIBGCC2_HAS_SF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_SF_MODE
> -#define LIBGCC2_HAS_SF_MODE (BITS_PER_UNIT == 8)
> +#ifdef __LIBGCC_HAS_DF_MODE__
> +#define LIBGCC2_HAS_DF_MODE 1
> +#else
> +#define LIBGCC2_HAS_DF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_DF_MODE
> -#define LIBGCC2_HAS_DF_MODE \
> - (BITS_PER_UNIT == 8 \
> - && (__SIZEOF_DOUBLE__ * __CHAR_BIT__ == 64 \
> - || LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64))
> -#endif
> -
> typedef int QItype __attribute__ ((mode (QI)));
> typedef unsigned int UQItype __attribute__ ((mode (QI)));
> typedef int HItype __attribute__ ((mode (HI)));
> Index: libgcc/libgcc2.h
> ===================================================================
> --- libgcc/libgcc2.h (revision 215170)
> +++ libgcc/libgcc2.h (working copy)
> @@ -38,25 +38,28 @@ extern void __eprintf (const char *, const char *,
> #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
> #endif
>
> -#ifndef LIBGCC2_HAS_SF_MODE
> -#define LIBGCC2_HAS_SF_MODE (BITS_PER_UNIT == 8)
> +#ifdef __LIBGCC_HAS_SF_MODE__
> +#define LIBGCC2_HAS_SF_MODE 1
> +#else
> +#define LIBGCC2_HAS_SF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_DF_MODE
> -#define LIBGCC2_HAS_DF_MODE \
> - (BITS_PER_UNIT == 8 \
> - && (__SIZEOF_DOUBLE__ * __CHAR_BIT__ == 64 \
> - || LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64))
> +#ifdef __LIBGCC_HAS_DF_MODE__
> +#define LIBGCC2_HAS_DF_MODE 1
> +#else
> +#define LIBGCC2_HAS_DF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_XF_MODE
> -#define LIBGCC2_HAS_XF_MODE \
> - (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
> +#ifdef __LIBGCC_HAS_XF_MODE__
> +#define LIBGCC2_HAS_XF_MODE 1
> +#else
> +#define LIBGCC2_HAS_XF_MODE 0
> #endif
>
> -#ifndef LIBGCC2_HAS_TF_MODE
> -#define LIBGCC2_HAS_TF_MODE \
> - (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
> +#ifdef __LIBGCC_HAS_TF_MODE__
> +#define LIBGCC2_HAS_TF_MODE 1
> +#else
> +#define LIBGCC2_HAS_TF_MODE 0
> #endif
>
> #ifndef __LIBGCC_SF_MANT_DIG__
>
> --
> Joseph S. Myers
> joseph@codesourcery.com