summaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2019-11-07 09:19:31 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2019-11-07 09:19:31 +0000
commit29f3def30844dd13e79972fa03a50af68120f7ac (patch)
tree270260e9909fa2a95f28ea376624c6c735ad5f73 /gcc/config/avr
parent76bc24ff68284d90bc8d334b72c9690382747add (diff)
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) <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
Diffstat (limited to 'gcc/config/avr')
-rw-r--r--gcc/config/avr/avr-c.c49
-rw-r--r--gcc/config/avr/avr.c3
-rw-r--r--gcc/config/avr/avr.h12
-rw-r--r--gcc/config/avr/avr.opt18
-rw-r--r--gcc/config/avr/driver-avr.c57
-rw-r--r--gcc/config/avr/genmultilib.awk64
-rw-r--r--gcc/config/avr/t-avr14
-rw-r--r--gcc/config/avr/t-multilib46
8 files changed, 207 insertions, 56 deletions
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=<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)
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 (" %<mdouble=* -mdouble=", dbl == 32 ? "32" : "64",
+ " %<mlong-double=* -mlong-double=", ldb == 32 ? "32" : "64",
+ NULL);
+}
diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk
index a5f9c773f1f..12280228377 100644
--- a/gcc/config/avr/genmultilib.awk
+++ b/gcc/config/avr/genmultilib.awk
@@ -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
}
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
# <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
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
-# <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