From 29f3def30844dd13e79972fa03a50af68120f7ac Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Thu, 7 Nov 2019 09:19:31 +0000 Subject: [PATCH] Support 64-bit double and 64-bit long double configurations. gcc/ Support 64-bit double and 64-bit long double configurations. PR target/92055 * config.gcc (tm_defines) [avr]: Set from --with-double=, --with-long-double=. * config/avr/t-multilib: Remove. * config/avr/t-avr: Output of genmultilib.awk is now fully dynamically generated and no more part of the repo. (HAVE_DOUBLE_MULTILIB, HAVE_LONG_DOUBLE_MULTILIB): New variables. Pass them down to... * config/avr/genmultilib.awk: ...here and handle them. * gcc/config/avr/avr.opt (-mdouble=, avr_double). New option and var. (-mlong-double=, avr_long_double). New option and var. * common/config/avr/avr-common.c (opts.h, diagnostic.h): Include. (TARGET_OPTION_OPTIMIZATION_TABLE) <-mdouble=, -mlong-double=>: Set default as requested by --with-double= (TARGET_HANDLE_OPTION): Define to this... (avr_handle_option): ...new hook worker. * config/avr/avr.h (DOUBLE_TYPE_SIZE): Define to avr_double. (LONG_DOUBLE_TYPE_SIZE): Define to avr_long_double. (avr_double_lib): New proto for spec function. (EXTRA_SPEC_FUNCTIONS) : Add. (DRIVER_SELF_SPECS): Call %:double-lib. * config/avr/avr.c (avr_option_override): Assert sizeof(long double) >= sizeof(double) for the target. * config/avr/avr-c.c (avr_cpu_cpp_builtins) [__HAVE_DOUBLE_MULTILIB__, __HAVE_LONG_DOUBLE_MULTILIB__] [__HAVE_DOUBLE64__, __HAVE_DOUBLE32__, __DEFAULT_DOUBLE__=] [__HAVE_LONG_DOUBLE64__, __HAVE_LONG_DOUBLE32__] [__HAVE_LONG_DOUBLE_IS_DOUBLE__, __DEFAULT_LONG_DOUBLE__=]: New built-in define depending on --with-double=, --with-long-double=. * config/avr/driver-avr.c (avr_double_lib): New spec function. * doc/invoke.tex (AVR Options) <-mdouble=,-mlong-double=>: Doc. * doc/install.texi (Cross-Compiler-Specific Options) <--with-double=, --with-long-double=>: Doc. libgcc/ Support 64-bit double and 64-bit long double configurations. PR target/92055 * config/avr/t-avr (HOST_LIBGCC2_CFLAGS): Only add -DF=SF if long double is a 32-bit type. * config/avr/t-avrlibc: Copy double64 and long-double64 multilib(s) from the vanilla one. * config/avr/t-copy-libgcc: New Makefile snip. From-SVN: r277908 --- gcc/ChangeLog | 38 ++++++++++++ gcc/common/config/avr/avr-common.c | 95 ++++++++++++++++++++++++++++++ gcc/config.gcc | 82 ++++++++++++++++++++++++++ gcc/config/avr/avr-c.c | 49 +++++++++++++++ gcc/config/avr/avr.c | 3 + gcc/config/avr/avr.h | 12 ++-- gcc/config/avr/avr.opt | 18 ++++++ gcc/config/avr/driver-avr.c | 57 ++++++++++++++++++ gcc/config/avr/genmultilib.awk | 64 +++++++++++++++++++- gcc/config/avr/t-avr | 14 ++++- gcc/config/avr/t-multilib | 46 --------------- gcc/doc/install.texi | 39 +++++++++++- gcc/doc/invoke.texi | 12 ++++ libgcc/ChangeLog | 11 ++++ libgcc/config.host | 3 + libgcc/config/avr/t-avr | 8 ++- libgcc/config/avr/t-avrlibc | 31 ++++++++++ libgcc/config/avr/t-copy-libgcc | 13 ++++ 18 files changed, 534 insertions(+), 61 deletions(-) delete mode 100644 gcc/config/avr/t-multilib create mode 100644 libgcc/config/avr/t-copy-libgcc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b6db832f9fe..d64d6b7139d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2019-11-07 Georg-Johann Lay + + Support 64-bit double and 64-bit long double configurations. + + PR target/92055 + * config.gcc (tm_defines) [avr]: Set from --with-double=, + --with-long-double=. + * config/avr/t-multilib: Remove. + * config/avr/t-avr: Output of genmultilib.awk is now fully + dynamically generated and no more part of the repo. + (HAVE_DOUBLE_MULTILIB, HAVE_LONG_DOUBLE_MULTILIB): New variables. + Pass them down to... + * config/avr/genmultilib.awk: ...here and handle them. + * gcc/config/avr/avr.opt (-mdouble=, avr_double). New option and var. + (-mlong-double=, avr_long_double). New option and var. + * common/config/avr/avr-common.c (opts.h, diagnostic.h): Include. + (TARGET_OPTION_OPTIMIZATION_TABLE) <-mdouble=, -mlong-double=>: + Set default as requested by --with-double= + (TARGET_HANDLE_OPTION): Define to this... + (avr_handle_option): ...new hook worker. + * config/avr/avr.h (DOUBLE_TYPE_SIZE): Define to avr_double. + (LONG_DOUBLE_TYPE_SIZE): Define to avr_long_double. + (avr_double_lib): New proto for spec function. + (EXTRA_SPEC_FUNCTIONS) : Add. + (DRIVER_SELF_SPECS): Call %:double-lib. + * config/avr/avr.c (avr_option_override): Assert + sizeof(long double) >= sizeof(double) for the target. + * config/avr/avr-c.c (avr_cpu_cpp_builtins) + [__HAVE_DOUBLE_MULTILIB__, __HAVE_LONG_DOUBLE_MULTILIB__] + [__HAVE_DOUBLE64__, __HAVE_DOUBLE32__, __DEFAULT_DOUBLE__=] + [__HAVE_LONG_DOUBLE64__, __HAVE_LONG_DOUBLE32__] + [__HAVE_LONG_DOUBLE_IS_DOUBLE__, __DEFAULT_LONG_DOUBLE__=]: + New built-in define depending on --with-double=, --with-long-double=. + * config/avr/driver-avr.c (avr_double_lib): New spec function. + * doc/invoke.tex (AVR Options) <-mdouble=,-mlong-double=>: Doc. + * doc/install.texi (Cross-Compiler-Specific Options) + <--with-double=, --with-long-double=>: Doc. + 2019-11-07 Richard Biener * dbgcnt.def (gimple_unroll): New. diff --git a/gcc/common/config/avr/avr-common.c b/gcc/common/config/avr/avr-common.c index dae42e7d46d..55a75790e1b 100644 --- a/gcc/common/config/avr/avr-common.c +++ b/gcc/common/config/avr/avr-common.c @@ -23,6 +23,8 @@ #include "tm.h" #include "common/common-target.h" #include "common/common-target-def.h" +#include "opts.h" +#include "diagnostic.h" /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ static const struct default_options avr_option_optimization_table[] = @@ -43,9 +45,102 @@ static const struct default_options avr_option_optimization_table[] = performance decrease. For the AVR though, disallowing data races introduces additional code in LIM and increases reg pressure. */ { OPT_LEVELS_ALL, OPT_fallow_store_data_races, NULL, 1 }, + +#if defined (WITH_DOUBLE64) + { OPT_LEVELS_ALL, OPT_mdouble_, NULL, 64 }, +#elif defined (WITH_DOUBLE32) + { OPT_LEVELS_ALL, OPT_mdouble_, NULL, 32 }, +#else +#error "align this with config.gcc" +#endif + +#if defined (WITH_LONG_DOUBLE64) + { OPT_LEVELS_ALL, OPT_mlong_double_, NULL, 64 }, +#elif defined (WITH_LONG_DOUBLE32) + { OPT_LEVELS_ALL, OPT_mlong_double_, NULL, 32 }, +#else +#error "align this with config.gcc" +#endif + { OPT_LEVELS_NONE, 0, NULL, 0 } }; + +/* Implement `TARGET_HANDLE_OPTION'. */ + +/* This is the same logic that driver-avr.c:avr_double_lib() applies + during DRIVER_SELF_SPECS, but this time we complain about -mdouble= + and -mlong-double= that are not provided by --with-double= resp. + --with-long-double= */ + +static bool +avr_handle_option (struct gcc_options *opts, struct gcc_options*, + const struct cl_decoded_option *decoded, location_t loc) +{ + int value = decoded->value; + + switch (decoded->opt_index) + { + case OPT_mdouble_: + if (value == 64) + { +#if !defined (HAVE_DOUBLE64) + error_at (loc, "option %<-mdouble=64%> is only available if " + "configured %<--with-double={64|64,32|32,64}%>"); +#endif + opts->x_avr_long_double = 64; + } + else if (value == 32) + { +#if !defined (HAVE_DOUBLE32) + error_at (loc, "option %<-mdouble=32%> is only available if " + "configured %<--with-double={|32|32,64|64,32}%>"); +#endif + } + else + gcc_unreachable(); + +#if defined (HAVE_LONG_DOUBLE_IS_DOUBLE) + opts->x_avr_long_double = value; +#endif + break; // -mdouble= + + case OPT_mlong_double_: + if (value == 64) + { +#if !defined (HAVE_LONG_DOUBLE64) + error_at (loc, "option %<-mlong-double=64%> is only available if " + "configured %<--with-long-double={64|64,32|32,64}%>, " + "or %<--with-long-double=double%> together with " + "%<--with-double={64|64,32|32,64}%>"); +#endif + } + else if (value == 32) + { +#if !defined (HAVE_LONG_DOUBLE32) + error_at (loc, "option %<-mlong-double=32%> is only available if " + "configured %<--with-long-double={|32|32,64|64,32}%>, " + "or %<--with-long-double=double%> together with " + "%<--with-double={|32|32,64|64,32}%>"); +#endif + opts->x_avr_double = 32; + } + else + gcc_unreachable(); + +#if defined (HAVE_LONG_DOUBLE_IS_DOUBLE) + opts->x_avr_double = value; +#endif + break; // -mlong-double= + } + + return true; +} + + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION avr_handle_option + #undef TARGET_OPTION_OPTIMIZATION_TABLE #define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table diff --git a/gcc/config.gcc b/gcc/config.gcc index d74bcbb9856..72f656408f1 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1287,6 +1287,88 @@ avr-*-*) tm_file="${tm_file} ${cpu_type}/avrlibc.h" tm_defines="${tm_defines} WITH_AVRLIBC" fi + case y${with_double} in + y | y32) + avr_double=32 + tm_defines="${tm_defines} HAVE_DOUBLE32" + ;; + y64) + avr_double=64 + tm_defines="${tm_defines} HAVE_DOUBLE64" + ;; + y64,32) + avr_double=64 + avr_double_multilib=1 + tm_defines="${tm_defines} HAVE_DOUBLE32" + tm_defines="${tm_defines} HAVE_DOUBLE64" + tm_defines="${tm_defines} HAVE_DOUBLE_MULTILIB" + ;; + y32,64) + avr_double=32 + avr_double_multilib=1 + tm_defines="${tm_defines} HAVE_DOUBLE32" + tm_defines="${tm_defines} HAVE_DOUBLE64" + tm_defines="${tm_defines} HAVE_DOUBLE_MULTILIB" + ;; + *) + echo "Error: --with-double= can only be used with: '32', '32,64', '64,32', '64'" 1>&2 + exit 1 + ;; + esac + case y${with_long_double} in + y | y32) + avr_long_double=32 + tm_defines="${tm_defines} HAVE_LONG_DOUBLE32" + ;; + y64) + avr_long_double=64 + tm_defines="${tm_defines} HAVE_LONG_DOUBLE64" + ;; + y64,32) + avr_long_double=64 + avr_long_double_multilib=1 + tm_defines="${tm_defines} HAVE_LONG_DOUBLE32" + tm_defines="${tm_defines} HAVE_LONG_DOUBLE64" + tm_defines="${tm_defines} HAVE_LONG_DOUBLE_MULTILIB" + ;; + y32,64) + avr_long_double=32 + avr_long_double_multilib=1 + tm_defines="${tm_defines} HAVE_LONG_DOUBLE32" + tm_defines="${tm_defines} HAVE_LONG_DOUBLE64" + tm_defines="${tm_defines} HAVE_LONG_DOUBLE_MULTILIB" + ;; + ydouble) + avr_long_double=${avr_double} + tm_defines="${tm_defines} HAVE_LONG_DOUBLE_IS_DOUBLE" + if test y${avr_double_multilib} = y1; then + tm_defines="${tm_defines} HAVE_LONG_DOUBLE32" + tm_defines="${tm_defines} HAVE_LONG_DOUBLE64" + else + tm_defines="${tm_defines} HAVE_LONG_DOUBLE${avr_long_double}" + fi + ;; + *) + echo "Error: --with-long_double= can only be used with: '32', '32,64', '64,32', '64', 'double'" 1>&2 + exit 1 + ;; + esac + if test ${avr_long_double}x${avr_long_double_multilib}y${avr_double_multilib}z = 32xy1z; then + if test y${with_long_double} != ydouble; then + echo "Error: --with-double=${with_double} requests a multilib for double, but long double is always 32 bits wide due to --with-long-double=${with_long_double}" 1>&2 + exit 1 + fi + fi + if test ${avr_double}x${avr_long_double_multilib}y${avr_double_multilib}z = 64x1yz; then + echo "Error: --with-long-double=${with_long_double} requests a multilib for long double, but double is always 64 bits wide due to --with-double=64" 1>&2 + exit 1 + fi + if test y${avr_double}${avr_long_double} = y6432; then + echo "Error: double default of 64 bits from --with-double=${with_double} conflicts with default of 32 bits for long double from --with-long-double=${with_long_double}" 1>&2 + exit 1 + fi + tm_defines="${tm_defines} WITH_DOUBLE${avr_double}" + tm_defines="${tm_defines} WITH_LONG_DOUBLE${avr_long_double}" tmake_file="${tmake_file} avr/t-avr avr/t-multilib" use_gcc_stdint=wrap extra_gcc_objs="driver-avr.o avr-devices.o" diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index e0ba5bd47af..91aaae0f035 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -390,6 +390,55 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) cpp_define (pfile, "__WITH_AVRLIBC__"); #endif /* WITH_AVRLIBC */ + // From configure --with-double={|32|32,64|64,32|64} + +#ifdef HAVE_DOUBLE_MULTILIB + cpp_define (pfile, "__HAVE_DOUBLE_MULTILIB__"); +#endif + +#ifdef HAVE_DOUBLE64 + cpp_define (pfile, "__HAVE_DOUBLE64__"); +#endif + +#ifdef HAVE_DOUBLE32 + cpp_define (pfile, "__HAVE_DOUBLE32__"); +#endif + +#if defined (WITH_DOUBLE64) + cpp_define (pfile, "__DEFAULT_DOUBLE__=64"); +#elif defined (WITH_DOUBLE32) + cpp_define (pfile, "__DEFAULT_DOUBLE__=32"); +#else +#error "align this with config.gcc" +#endif + + // From configure --with-long-double={|32|32,64|64,32|64|double} + +#ifdef HAVE_LONG_DOUBLE_MULTILIB + cpp_define (pfile, "__HAVE_LONG_DOUBLE_MULTILIB__"); +#endif + +#ifdef HAVE_LONG_DOUBLE64 + cpp_define (pfile, "__HAVE_LONG_DOUBLE64__"); +#endif + +#ifdef HAVE_LONG_DOUBLE32 + cpp_define (pfile, "__HAVE_LONG_DOUBLE32__"); +#endif + +#ifdef HAVE_LONG_DOUBLE_IS_DOUBLE + cpp_define (pfile, "__HAVE_LONG_DOUBLE_IS_DOUBLE__"); +#endif + +#if defined (WITH_LONG_DOUBLE64) + cpp_define (pfile, "__DEFAULT_LONG_DOUBLE__=64"); +#elif defined (WITH_LONG_DOUBLE32) + cpp_define (pfile, "__DEFAULT_LONG_DOUBLE__=32"); +#else +#error "align this with config.gcc" +#endif + + /* Define builtin macros so that the user can easily query whether non-generic address spaces (and which) are supported or not. This is only supported for C. For C++, a language extension is needed diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index fc213895091..8fc2e71489d 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -768,6 +768,9 @@ avr_option_override (void) if (!avr_set_core_architecture()) return; + /* Sould be set by avr-common.c */ + gcc_assert (avr_long_double >= avr_double && avr_double >= 32); + /* RAM addresses of some SFRs common to all devices in respective arch. */ /* SREG: Status Register containing flags like I (global IRQ) */ diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 2b3cfd1bc45..b38813d468b 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -140,8 +140,9 @@ FIXME: DRIVER_SELF_SPECS has changed. #define LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 16 : 32) #define LONG_LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 32 : 64) #define FLOAT_TYPE_SIZE 32 -#define DOUBLE_TYPE_SIZE 32 -#define LONG_DOUBLE_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE (avr_double) +#define LONG_DOUBLE_TYPE_SIZE (avr_long_double) + #define LONG_LONG_ACCUM_TYPE_SIZE 64 #define DEFAULT_SIGNED_CHAR 1 @@ -507,8 +508,10 @@ typedef struct avr_args (LENGTH = avr_adjust_insn_length (INSN, LENGTH)) extern const char *avr_devicespecs_file (int, const char**); +extern const char *avr_double_lib (int, const char**); -#define EXTRA_SPEC_FUNCTIONS \ +#define EXTRA_SPEC_FUNCTIONS \ + { "double-lib", avr_double_lib }, \ { "device-specs-file", avr_devicespecs_file }, /* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs. @@ -516,7 +519,8 @@ extern const char *avr_devicespecs_file (int, const char**); is used to diagnose problems with reading the specs file. */ #undef DRIVER_SELF_SPECS -#define DRIVER_SELF_SPECS \ +#define DRIVER_SELF_SPECS \ + " %:double-lib(%{m*:m%*})" \ " %:device-specs-file(device-specs%s %{mmcu=*:%*})" /* No libstdc++ for now. Empty string doesn't work. */ diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index 3fc83a2fdb1..ac2d9551258 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -115,6 +115,24 @@ mabsdata Target Report Mask(ABSDATA) Assume that all data in static storage can be accessed by LDS / STS. This option is only useful for reduced Tiny devices. +mdouble= +Target Report Joined RejectNegative Var(avr_double) Init(0) Enum(avr_bits_e) +mdouble= Use bits wide double type. + +mlong-double= +Target Report Joined RejectNegative Var(avr_long_double) Init(0) Enum(avr_bits_e) +mlong-double= Use bits wide long double type. + nodevicelib Driver Target Report RejectNegative Do not link against the device-specific library lib.a. + +Enum +Name(avr_bits_e) Type(int) +Available BITS selections: + +EnumValue +Enum(avr_bits_e) String(32) Value(32) + +EnumValue +Enum(avr_bits_e) String(64) Value(64) diff --git a/gcc/config/avr/driver-avr.c b/gcc/config/avr/driver-avr.c index 7b9e712be6b..a6239dac949 100644 --- a/gcc/config/avr/driver-avr.c +++ b/gcc/config/avr/driver-avr.c @@ -111,3 +111,60 @@ avr_devicespecs_file (int argc, const char **argv) #endif NULL); } + + +/* Re-build the -mdouble= and -mlong-double= options. This is needed + because multilib selection is based on the physical presence of an + option on the command line, which is not the case for, say, when the + double=64 multilib is to be selected by --with-double=64 but the user + does not specify -mdouble=64 explicitly. */ + +const char* +avr_double_lib (int argc, const char **argv) +{ +#if defined (WITH_DOUBLE64) + int dbl = 64; +#elif defined (WITH_DOUBLE32) + int dbl = 32; +#else +#error "align this with config.gcc" +#endif + +#if defined (WITH_LONG_DOUBLE64) + int ldb = 64; +#elif defined (WITH_LONG_DOUBLE32) + int ldb = 32; +#else +#error "align this with config.gcc" +#endif + + for (int i = 0; i < argc; i++) + { + if (strcmp (argv[i], "mdouble=32") == 0) + { + dbl = 32; +#ifdef HAVE_LONG_DOUBLE_IS_DOUBLE + ldb = dbl; +#endif + } + else if (strcmp (argv[i], "mdouble=64") == 0) + { + ldb = dbl = 64; + } + else if (strcmp (argv[i], "mlong-double=32") == 0) + { + ldb = dbl = 32; + } + else if (strcmp (argv[i], "mlong-double=64") == 0) + { + ldb = 64; +#ifdef HAVE_LONG_DOUBLE_IS_DOUBLE + dbl = ldb; +#endif + } + } + + return concat (" % MULTILIB_OPTIONS # m_dirnames <-> MULTILIB_DIRNAMES # m_required <-> MULTILIB_REQUIRED + # m_reuse <-> MULTILIB_REUSE m_sep = "" m_options = "\nMULTILIB_OPTIONS = " m_dirnames = "\nMULTILIB_DIRNAMES =" m_required = "\nMULTILIB_REQUIRED =" + m_reuse = "\nMULTILIB_REUSE =" + + have_double_multi = (HAVE_DOUBLE_MULTILIB == "HAVE_DOUBLE_MULTILIB") + have_long_double_multi = (HAVE_LONG_DOUBLE_MULTILIB == "HAVE_LONG_DOUBLE_MULTILIB") } ################################################################## @@ -130,7 +141,26 @@ BEGIN { # leading "mmcu=avr2/" in order not to confuse genmultilib. gsub (/^mmcu=avr2\//, "", opts) if (opts != "mmcu=avr2") + { m_required = m_required " \\\n\t" opts + if (have_double_multi && have_long_double_multi) + { + m_required = m_required " \\\n\t" opts "/" opt_double64 + m_required = m_required " \\\n\t" opts "/" opt_long_double64 + + # -mlong-double=64 -mdouble=64 is the same as -mdouble=64, + # hence add a respective reuse. + d_opts = opts "/" opt_double64 + d_reuse = opts "/" opt_double64 "/" opt_long_double64 + gsub (/=/, ".", d_opts) + gsub (/=/, ".", d_reuse) + m_reuse = m_reuse " \\\n\t" d_opts "=" d_reuse + } + else if (have_double_multi) + m_required = m_required " \\\n\t" opts "/" opt_double64 + else if (have_long_double_multi) + m_required = m_required " \\\n\t" opts "/" opt_long_double64 + } } } @@ -143,9 +173,37 @@ END { # Output that Stuff ############################################################ - # Intended Target: ./gcc/config/avr/t-multilib + # Intended Target: $(top_builddir)/gcc/t-multilib-avr + + if (have_double_multi && have_long_double_multi) + { + print m_options " " opt_tiny " " opt_rcall " " opt_double64 "/" opt_long_double64 + print m_dirnames " " dir_tiny " " dir_rcall " " dir_double64 " " dir_long_double64 + # Notice that the ./double64 and ./long-double64 variants cannot + # be copied by t-avrlibc because the . default multilib is built + # after all the others. + m_required = m_required " \\\n\t" opt_double64 + m_required = m_required " \\\n\t" opt_long_double64 + m_reuse = m_reuse " \\\n\tmdouble.64=mdouble.64/mlong-double.64" + } + else if (have_double_multi) + { + print m_options " " opt_tiny " " opt_rcall " " opt_double64 + print m_dirnames " " dir_tiny " " dir_rcall " " dir_double64 + m_required = m_required " \\\n\t" opt_double64 + } + else if (have_long_double_multi) + { + print m_options " " opt_tiny " " opt_rcall " " opt_long_double64 + print m_dirnames " " dir_tiny " " dir_rcall " " dir_long_double64 + m_required = m_required " \\\n\t" opt_long_double64 + } + else + { + print m_options " " opt_tiny " " opt_rcall + print m_dirnames " " dir_tiny " " dir_rcall + } - print m_options " " opt_tiny " " opt_rcall - print m_dirnames " " dir_tiny " " dir_rcall print m_required + print m_reuse } diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr index d5a78f90ef5..23dae38c66f 100644 --- a/gcc/config/avr/t-avr +++ b/gcc/config/avr/t-avr @@ -16,6 +16,9 @@ # along with GCC; see the file COPYING3. If not see # . +HAVE_DOUBLE_MULTILIB = $(findstring HAVE_DOUBLE_MULTILIB, $(tm_defines)) +HAVE_LONG_DOUBLE_MULTILIB = $(findstring HAVE_LONG_DOUBLE_MULTILIB, $(tm_defines)) + PASSES_EXTRA += $(srcdir)/config/avr/avr-passes.def driver-avr.o: $(srcdir)/config/avr/driver-avr.c \ @@ -93,9 +96,14 @@ install-device-specs: s-device-specs installdirs # MULTILIB_OPTIONS # MULTILIB_DIRNAMES # MULTILIB_REQUIRED +# MULTILIB_REUSE -s-mlib: $(srcdir)/config/avr/t-multilib +multilib.h Makefile s-mlib: t-multilib-avr -$(srcdir)/config/avr/t-multilib: $(srcdir)/config/avr/genmultilib.awk \ +t-multilib-avr: $(srcdir)/config/avr/genmultilib.awk \ $(AVR_MCUS) - $(AWK) -f $< $< $(AVR_MCUS) > $@ + $(AWK) -v HAVE_DOUBLE_MULTILIB=$(HAVE_DOUBLE_MULTILIB) \ + -v HAVE_LONG_DOUBLE_MULTILIB=$(HAVE_LONG_DOUBLE_MULTILIB) \ + -f $< $< $(AVR_MCUS) > $@ + +include t-multilib-avr diff --git a/gcc/config/avr/t-multilib b/gcc/config/avr/t-multilib deleted file mode 100644 index 8bda0f747c9..00000000000 --- a/gcc/config/avr/t-multilib +++ /dev/null @@ -1,46 +0,0 @@ -# Auto-generated Makefile Snip -# Generated by : ./gcc/config/avr/genmultilib.awk -# Generated from : ./gcc/config/avr/avr-mcus.def -# Used by : tmake_file from Makefile and genmultilib - -# Copyright (C) 2011-2019 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3, or (at your option) any later -# version. -# -# GCC is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega3/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8 mshort-calls - -MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack short-calls - -MULTILIB_REQUIRED = \ - msp8 \ - mmcu=avr25 \ - mmcu=avr25/msp8 \ - mmcu=avr3 \ - mmcu=avr31 \ - mmcu=avr35 \ - mmcu=avr4 \ - mmcu=avr5 \ - mmcu=avr51 \ - mmcu=avr6 \ - mmcu=avrxmega2 \ - mmcu=avrxmega3/mshort-calls \ - mmcu=avrxmega3 \ - mmcu=avrxmega4 \ - mmcu=avrxmega5 \ - mmcu=avrxmega6 \ - mmcu=avrxmega7 \ - mmcu=avrtiny diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 55ef4ca7f24..2cb8a342a2c 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -2276,16 +2276,49 @@ being used as the target C library. This causes @code{__eprintf} to be omitted from @file{libgcc.a} on the assumption that it will be provided by @samp{newlib}. +@html + +@end html @item --with-avrlibc -Specifies that @samp{AVR-Libc} is -being used as the target C library. This causes float support +Only supported for the AVR target. Specifies that @samp{AVR-Libc} is +being used as the target C@tie{} library. This causes float support functions like @code{__addsf3} to be omitted from @file{libgcc.a} on the assumption that it will be provided by @file{libm.a}. For more technical details, cf. @uref{http://gcc.gnu.org/PR54461,,PR54461}. -This option is only supported for the AVR target. It is not supported for +It is not supported for RTEMS configurations, which currently use newlib. The option is supported since version 4.7.2 and is the default in 4.8.0 and newer. +@item --with-double=@{32|64|32,64|64,32@} +@itemx --with-long-double=@{32|64|32,64|64,32|double@} +Only supported for the AVR target since version@tie{}10. +Specify the default layout available for the C/C++ @samp{double} +and @samp{long double} type, respectively. The following rules apply: +@itemize +@item +The first value after the @samp{=} specifies the default layout (in bits) +of the type and also the default for the @option{-mdouble=} resp. +@option{-mlong-double=} compiler option. +@item +If more than one value is specified, respective multilib variants are +available, and @option{-mdouble=} resp. @option{-mlong-double=} acts +as a multilib option. +@item +If @option{--with-long-double=double} is specified, @samp{double} and +@samp{long double} will have the same layout. +@item +If the configure option is not set, it defaults to @samp{32} which +is compatible with older versions of the compiler that use non-standard +32-bit types for @samp{double} and @samp{long double}. +@end itemize +Not all combinations of @option{--with-double=} and +@option{--with-long-double=} are valid. For example, the combination +@option{--with-double=32,64} @option{--with-long-double=32} will be +rejected because the first option specifies the availability of +multilibs for @samp{double}, whereas the second option implies +that @samp{long double} --- and hence also @samp{double} --- is always +32@tie{}bits wide. + @item --with-nds32-lib=@var{library} Specifies that @var{library} setting is used for building @file{libgcc.a}. Currently, the valid @var{library} is @samp{newlib} or @samp{mculib}. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d34ac6cd0c9..42db3287cae 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -723,6 +723,7 @@ Objective-C and Objective-C++ Dialects}. @gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args @gol -mbranch-cost=@var{cost} @gol -mcall-prologues -mgas-isr-prologues -mint8 @gol +-mdouble=@var{bits} -mlong-double=@var{bits} @gol -mn_flash=@var{size} -mno-interrupts @gol -mmain-is-OS_task -mrelax -mrmw -mstrict-X -mtiny-stack @gol -mfract-convert-truncate @gol @@ -18279,6 +18280,17 @@ integers. The default branch cost is 0. Functions prologues/epilogues are expanded as calls to appropriate subroutines. Code size is smaller. +@item -mdouble=@var{bits} +@itemx -mlong-double=@var{bits} +@opindex mdouble +@opindex mlong-double +Set the size (in bits) of the @code{double} or @code{long double} type, +respectively. Possible values for @var{bits} are 32 an 64. +Whether or not a specific value for @var{bits} is allowed depends on +the @code{--with--double=} and @code{--with-long-double=} +@w{@uref{https://gcc.gnu.org/install/configure.html#avr,configure options}}, +and the same applies for the default values of the options. + @item -mgas-isr-prologues @opindex mgas-isr-prologues Interrupt service routines (ISRs) may use the @code{__gcc_isr} pseudo diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index c528cec2db3..ff26a0ced5d 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,14 @@ +2019-11-07 Georg-Johann Lay + + Support 64-bit double and 64-bit long double configurations. + + PR target/92055 + * config/avr/t-avr (HOST_LIBGCC2_CFLAGS): Only add -DF=SF if + long double is a 32-bit type. + * config/avr/t-avrlibc: Copy double64 and long-double64 + multilib(s) from the vanilla one. + * config/avr/t-copy-libgcc: New Makefile snip. + 2019-11-04 Jozef Lawrynowicz * crtstuff.c: Define USE_TM_CLONE_REGISTRY to 0 if it's undefined and diff --git a/libgcc/config.host b/libgcc/config.host index 122113fc519..0b8eb4e5d73 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -505,6 +505,9 @@ avr-*-*) tmake_file="$tmake_file ${cpu_type}/t-avrlibc" fi tm_file="$tm_file avr/avr-lib.h" + if test x${with_fixed_point} = xno; then + fixed_point=no + fi ;; bfin*-elf*) tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-libgcc-pic t-fdpbit" diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index c420c5d8fb9..e4f867be3d8 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -112,10 +112,14 @@ LIB2FUNCS_EXCLUDE = \ _clrsbdi2 \ -# We do not have the DF type. +ifeq ($(long_double_type_size),32) +# We do not have the DFtype. +HOST_LIBGCC2_CFLAGS += -DDF=SF +endif + # Most of the C functions in libgcc2 use almost all registers, # so use -mcall-prologues for smaller code size. -HOST_LIBGCC2_CFLAGS += -DDF=SF -Dinhibit_libc -mcall-prologues -Os +HOST_LIBGCC2_CFLAGS += -Dinhibit_libc -mcall-prologues -Os # Extra 16-bit integer functions. intfuncs16 = _absvXX2 _addvXX3 _subvXX3 _mulvXX3 _negvXX2 _clrsbXX2 diff --git a/libgcc/config/avr/t-avrlibc b/libgcc/config/avr/t-avrlibc index d2c8b870aab..2424d663565 100644 --- a/libgcc/config/avr/t-avrlibc +++ b/libgcc/config/avr/t-avrlibc @@ -64,3 +64,34 @@ LIB2FUNCS_EXCLUDE += \ _fixunssfsi _fixsfdi \ _fixunssfdi \ _floatdisf _floatundisf + +ifneq (,$(findstring avr,$(MULTISUBDIR))) + +# We are not in the avr2 (default) subdir, hence copying will work. +# In default dir, copying won'twork because the default multilib is +# built after all the others. + +ifneq (,$(findstring double64,$(MULTISUBDIR))) + +# We are in double64/libgcc or long-double64/libgcc: +# Just copy from the [long ]double=float multilib; we would remove any DFmode +# bits from this multilib variant, anyway, because the current assumption +# is that avr-libc hosts *all* the IEEE-double stuff. + +LIB2FUNCS_EXCLUDE := % +LIB1ASMFUNCS := +libgcc-objects := +libgcov-objects := +objects := + +t-copy-libgcc.dep: $(srcdir)/config/avr/t-copy-libgcc + -rm -f libgcc.a + -rm -f libgcov.a + cp $< $@ + +libgcc.a libgcov.a libgcc_tm.h: t-copy-libgcc.dep + +Makefile: t-copy-libgcc.dep + +endif +endif diff --git a/libgcc/config/avr/t-copy-libgcc b/libgcc/config/avr/t-copy-libgcc new file mode 100644 index 00000000000..d34cbde731b --- /dev/null +++ b/libgcc/config/avr/t-copy-libgcc @@ -0,0 +1,13 @@ +# Only used with --with-avrlibc & (-mlong-double=64 | -mdouble=64) +# +# Inserted at the end of Makefile by magic[tm]. +# We need this *after* Makefile's rules so we can override them. + +libgcc.a: ../../libgcc/libgcc.a + cp $< $@ + +libgcov.a: ../../libgcc/libgcov.a + @: +ifeq ($(enable_gcov),yes) + cp $< $@ +endif