diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2019-11-07 09:19:31 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2019-11-07 09:19:31 +0000 |
commit | 29f3def30844dd13e79972fa03a50af68120f7ac (patch) | |
tree | 270260e9909fa2a95f28ea376624c6c735ad5f73 /gcc/config/avr | |
parent | 76bc24ff68284d90bc8d334b72c9690382747add (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.c | 49 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 3 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 12 | ||||
-rw-r--r-- | gcc/config/avr/avr.opt | 18 | ||||
-rw-r--r-- | gcc/config/avr/driver-avr.c | 57 | ||||
-rw-r--r-- | gcc/config/avr/genmultilib.awk | 64 | ||||
-rw-r--r-- | gcc/config/avr/t-avr | 14 | ||||
-rw-r--r-- | gcc/config/avr/t-multilib | 46 |
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 |