summaryrefslogtreecommitdiff
path: root/gcc/common
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/common
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/common')
-rw-r--r--gcc/common/config/avr/avr-common.c95
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