Support 64-bit double and 64-bit long double configurations.
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 7 Nov 2019 09:19:31 +0000 (09:19 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Thu, 7 Nov 2019 09:19:31 +0000 (09:19 +0000)
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) <double-lib>: 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

18 files changed:
gcc/ChangeLog
gcc/common/config/avr/avr-common.c
gcc/config.gcc
gcc/config/avr/avr-c.c
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/avr/avr.opt
gcc/config/avr/driver-avr.c
gcc/config/avr/genmultilib.awk
gcc/config/avr/t-avr
gcc/config/avr/t-multilib [deleted file]
gcc/doc/install.texi
gcc/doc/invoke.texi
libgcc/ChangeLog
libgcc/config.host
libgcc/config/avr/t-avr
libgcc/config/avr/t-avrlibc
libgcc/config/avr/t-copy-libgcc [new file with mode: 0644]

index b6db832..d64d6b7 100644 (file)
@@ -1,3 +1,41 @@
+2019-11-07  Georg-Johann Lay  <avr@gjlay.de>
+
+       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) <double-lib>: 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  <rguenther@suse.de>
 
        * dbgcnt.def (gimple_unroll): New.
index dae42e7..55a7579 100644 (file)
@@ -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
 
index d74bcbb..72f6564 100644 (file)
@@ -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"
index e0ba5bd..91aaae0 100644 (file)
@@ -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
index fc21389..8fc2e71 100644 (file)
@@ -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) */
index 2b3cfd1..b38813d 100644 (file)
@@ -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.  */
index 3fc83a2..ac2d955 100644 (file)
@@ -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=<BITS> Use <BITS> bits wide double type.
+
+mlong-double=
+Target Report Joined RejectNegative Var(avr_long_double) Init(0) Enum(avr_bits_e)
+mlong-double=<BITS>    Use <BITS> bits wide long double type.
+
 nodevicelib
 Driver Target Report RejectNegative
 Do not link against the device-specific library lib<MCU>.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)
index 7b9e712..a6239da 100644 (file)
@@ -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 (" %<mdouble=* -mdouble=", dbl == 32 ? "32" : "64",
+                 " %<mlong-double=* -mlong-double=", ldb == 32 ? "32" : "64",
+                 NULL);
+}
index a5f9c77..1228022 100644 (file)
@@ -38,15 +38,26 @@ BEGIN {
     dir_rcall = "short-calls"
     opt_rcall = "mshort-calls"
 
+    dir_double64 = "double64"
+    opt_double64 = "mdouble=64"
+
+    dir_long_double64 = "long-double64"
+    opt_long_double64 = "mlong-double=64"
+
     #    awk Variable         Makefile Variable  
     #  ------------------------------------------
     #    m_options     <->    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
 }
index d5a78f9..23dae38 100644 (file)
@@ -16,6 +16,9 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
+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 (file)
index 8bda0f7..0000000
+++ /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
-# <http://www.gnu.org/licenses/>.
-
-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
index 55ef4ca..2cb8a34 100644 (file)
@@ -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
+<a name="avr"></a>
+@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}.
index d34ac6c..42db328 100644 (file)
@@ -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
index c528cec..ff26a0c 100644 (file)
@@ -1,3 +1,14 @@
+2019-11-07  Georg-Johann Lay  <avr@gjlay.de>
+
+       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  <jozef.l@mittosystems.com>
 
        * crtstuff.c: Define USE_TM_CLONE_REGISTRY to 0 if it's undefined and
index 122113f..0b8eb4e 100644 (file)
@@ -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"
index c420c5d..e4f867b 100644 (file)
@@ -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
index d2c8b87..2424d66 100644 (file)
@@ -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 (file)
index 0000000..d34cbde
--- /dev/null
@@ -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