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/common | |
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/common')
-rw-r--r-- | gcc/common/config/avr/avr-common.c | 95 |
1 files changed, 95 insertions, 0 deletions
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 |