/* Define builtin-in macros for the C family front ends.
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Copyright (C) 2002-2020 Free Software Foundation, Inc.
This file is part of GCC.
#include "coretypes.h"
#include "target.h"
#include "c-common.h"
+#include "memmodel.h"
#include "tm_p.h" /* For TARGET_CPU_CPP_BUILTINS & friends. */
#include "stringpool.h"
#include "stor-layout.h"
#include "output.h" /* For user_label_prefix. */
#include "debug.h" /* For dwarf2out_do_cfi_asm. */
#include "common/common-target.h"
-#include "cpp-id-data.h"
#include "cppbuiltin.h"
#ifndef TARGET_OS_CPP_BUILTINS
static void builtin_define_constants (const char *, tree);
static void builtin_define_type_max (const char *, tree);
static void builtin_define_type_minmax (const char *, const char *, tree);
+static void builtin_define_type_width (const char *, tree, tree);
static void builtin_define_float_constants (const char *,
const char *,
const char *,
switch (mode)
{
#ifdef HAVE_fmasf4
- case SFmode:
+ case E_SFmode:
return !!HAVE_fmasf4;
#endif
#ifdef HAVE_fmadf4
- case DFmode:
+ case E_DFmode:
return !!HAVE_fmadf4;
#endif
+#ifdef HAVE_fmakf4 /* PowerPC if long double != __float128. */
+ case E_KFmode:
+ return !!HAVE_fmakf4;
+#endif
+
#ifdef HAVE_fmaxf4
- case XFmode:
+ case E_XFmode:
return !!HAVE_fmaxf4;
#endif
#ifdef HAVE_fmatf4
- case TFmode:
+ case E_TFmode:
return !!HAVE_fmatf4;
#endif
const double log10_2 = .30102999566398119521;
double log10_b;
const struct real_format *fmt;
- const struct real_format *ldfmt;
+ const struct real_format *widefmt;
char name[64], buf[128];
int dig, min_10_exp, max_10_exp;
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
gcc_assert (fmt->b != 10);
- ldfmt = REAL_MODE_FORMAT (TYPE_MODE (long_double_type_node));
- gcc_assert (ldfmt->b != 10);
+ widefmt = REAL_MODE_FORMAT (TYPE_MODE (long_double_type_node));
+ gcc_assert (widefmt->b != 10);
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ {
+ tree wtype = FLOATN_NX_TYPE_NODE (i);
+ if (wtype != NULL_TREE)
+ {
+ const struct real_format *wfmt
+ = REAL_MODE_FORMAT (TYPE_MODE (wtype));
+ gcc_assert (wfmt->b != 10);
+ if (wfmt->p > widefmt->p)
+ widefmt = wfmt;
+ }
+ }
/* The radix of the exponent representation. */
if (type == float_type_node)
floating type, but we want this value for rendering constants below. */
{
double d_decimal_dig
- = 1 + (fmt->p < ldfmt->p ? ldfmt->p : fmt->p) * log10_b;
+ = 1 + (fmt->p < widefmt->p ? widefmt->p : fmt->p) * log10_b;
decimal_dig = d_decimal_dig;
if (decimal_dig < d_decimal_dig)
decimal_dig++;
if (type_decimal_dig < type_d_decimal_dig)
type_decimal_dig++;
}
+ /* Define __DECIMAL_DIG__ to the value for long double to be
+ compatible with C99 and C11; see DR#501 and N2108. */
if (type == long_double_type_node)
- builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
- else
- {
- sprintf (name, "__%s_DECIMAL_DIG__", name_prefix);
- builtin_define_with_int_value (name, type_decimal_dig);
- }
+ builtin_define_with_int_value ("__DECIMAL_DIG__", type_decimal_dig);
+ sprintf (name, "__%s_DECIMAL_DIG__", name_prefix);
+ builtin_define_with_int_value (name, type_decimal_dig);
/* Since, for the supported formats, B is always a power of 2, we
construct the following numbers directly as a hexadecimal
constants. */
- get_max_float (fmt, buf, sizeof (buf));
+ get_max_float (fmt, buf, sizeof (buf), false);
sprintf (name, "__%s_MAX__", name_prefix);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
+ get_max_float (fmt, buf, sizeof (buf), true);
+
+ sprintf (name, "__%s_NORM_MAX__", name_prefix);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
+
/* The minimum normalized positive floating-point number,
b**(emin-1). */
sprintf (name, "__%s_MIN__", name_prefix);
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
/* Note whether we have fast FMA. */
- if (mode_has_fma (TYPE_MODE (type)))
+ if (mode_has_fma (TYPE_MODE (type)) && fma_suffix != NULL)
{
sprintf (name, "__FP_FAST_FMA%s", fma_suffix);
builtin_define_with_int_value (name, 1);
builtin_define_constants ("__INTMAX_C", intmax_type_node);
builtin_define_type_max ("__UINTMAX_MAX__", uintmax_type_node);
builtin_define_constants ("__UINTMAX_C", uintmax_type_node);
+ builtin_define_type_width ("__INTMAX_WIDTH__", intmax_type_node,
+ uintmax_type_node);
if (sig_atomic_type_node)
- builtin_define_type_minmax ("__SIG_ATOMIC_MIN__", "__SIG_ATOMIC_MAX__",
- sig_atomic_type_node);
+ {
+ builtin_define_type_minmax ("__SIG_ATOMIC_MIN__", "__SIG_ATOMIC_MAX__",
+ sig_atomic_type_node);
+ builtin_define_type_width ("__SIG_ATOMIC_WIDTH__", sig_atomic_type_node,
+ NULL_TREE);
+ }
if (int8_type_node)
builtin_define_type_max ("__INT8_MAX__", int8_type_node);
if (int16_type_node)
{
builtin_define_type_max ("__INT_LEAST8_MAX__", int_least8_type_node);
builtin_define_constants ("__INT8_C", int_least8_type_node);
+ builtin_define_type_width ("__INT_LEAST8_WIDTH__", int_least8_type_node,
+ uint_least8_type_node);
}
if (int_least16_type_node)
{
builtin_define_type_max ("__INT_LEAST16_MAX__", int_least16_type_node);
builtin_define_constants ("__INT16_C", int_least16_type_node);
+ builtin_define_type_width ("__INT_LEAST16_WIDTH__",
+ int_least16_type_node,
+ uint_least16_type_node);
}
if (int_least32_type_node)
{
builtin_define_type_max ("__INT_LEAST32_MAX__", int_least32_type_node);
builtin_define_constants ("__INT32_C", int_least32_type_node);
+ builtin_define_type_width ("__INT_LEAST32_WIDTH__",
+ int_least32_type_node,
+ uint_least32_type_node);
}
if (int_least64_type_node)
{
builtin_define_type_max ("__INT_LEAST64_MAX__", int_least64_type_node);
builtin_define_constants ("__INT64_C", int_least64_type_node);
+ builtin_define_type_width ("__INT_LEAST64_WIDTH__",
+ int_least64_type_node,
+ uint_least64_type_node);
}
if (uint_least8_type_node)
{
builtin_define_constants ("__UINT64_C", uint_least64_type_node);
}
if (int_fast8_type_node)
- builtin_define_type_max ("__INT_FAST8_MAX__", int_fast8_type_node);
+ {
+ builtin_define_type_max ("__INT_FAST8_MAX__", int_fast8_type_node);
+ builtin_define_type_width ("__INT_FAST8_WIDTH__", int_fast8_type_node,
+ uint_fast8_type_node);
+ }
if (int_fast16_type_node)
- builtin_define_type_max ("__INT_FAST16_MAX__", int_fast16_type_node);
+ {
+ builtin_define_type_max ("__INT_FAST16_MAX__", int_fast16_type_node);
+ builtin_define_type_width ("__INT_FAST16_WIDTH__", int_fast16_type_node,
+ uint_fast16_type_node);
+ }
if (int_fast32_type_node)
- builtin_define_type_max ("__INT_FAST32_MAX__", int_fast32_type_node);
+ {
+ builtin_define_type_max ("__INT_FAST32_MAX__", int_fast32_type_node);
+ builtin_define_type_width ("__INT_FAST32_WIDTH__", int_fast32_type_node,
+ uint_fast32_type_node);
+ }
if (int_fast64_type_node)
- builtin_define_type_max ("__INT_FAST64_MAX__", int_fast64_type_node);
+ {
+ builtin_define_type_max ("__INT_FAST64_MAX__", int_fast64_type_node);
+ builtin_define_type_width ("__INT_FAST64_WIDTH__", int_fast64_type_node,
+ uint_fast64_type_node);
+ }
if (uint_fast8_type_node)
builtin_define_type_max ("__UINT_FAST8_MAX__", uint_fast8_type_node);
if (uint_fast16_type_node)
if (uint_fast64_type_node)
builtin_define_type_max ("__UINT_FAST64_MAX__", uint_fast64_type_node);
if (intptr_type_node)
- builtin_define_type_max ("__INTPTR_MAX__", intptr_type_node);
+ {
+ builtin_define_type_max ("__INTPTR_MAX__", intptr_type_node);
+ builtin_define_type_width ("__INTPTR_WIDTH__", intptr_type_node,
+ uintptr_type_node);
+ }
if (uintptr_type_node)
builtin_define_type_max ("__UINTPTR_MAX__", uintptr_type_node);
}
(have_swap[SWAP_INDEX (boolean_type_node)]? 2 : 1));
builtin_define_with_int_value ("__GCC_ATOMIC_CHAR_LOCK_FREE",
(have_swap[SWAP_INDEX (signed_char_type_node)]? 2 : 1));
+ if (flag_char8_t)
+ builtin_define_with_int_value ("__GCC_ATOMIC_CHAR8_T_LOCK_FREE",
+ (have_swap[SWAP_INDEX (char8_type_node)]? 2 : 1));
builtin_define_with_int_value ("__GCC_ATOMIC_CHAR16_T_LOCK_FREE",
(have_swap[SWAP_INDEX (char16_type_node)]? 2 : 1));
builtin_define_with_int_value ("__GCC_ATOMIC_CHAR32_T_LOCK_FREE",
(have_swap[psize]? 2 : 1));
}
+/* Return TRUE if the implicit excess precision in which the back-end will
+ compute floating-point calculations is not more than the explicit
+ excess precision that the front-end will apply under
+ -fexcess-precision=[standard|fast].
+
+ More intuitively, return TRUE if the excess precision proposed by the
+ front-end is the excess precision that will actually be used. */
+
+static bool
+c_cpp_flt_eval_method_iec_559 (void)
+{
+ enum excess_precision_type front_end_ept
+ = (flag_excess_precision == EXCESS_PRECISION_STANDARD
+ ? EXCESS_PRECISION_TYPE_STANDARD
+ : EXCESS_PRECISION_TYPE_FAST);
+
+ enum flt_eval_method back_end
+ = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT);
+
+ enum flt_eval_method front_end
+ = targetm.c.excess_precision (front_end_ept);
+
+ return excess_precision_mode_join (front_end, back_end) == front_end;
+}
+
/* Return the value for __GCC_IEC_559. */
static int
cpp_iec_559_value (void)
|| !dfmt->has_signed_zero)
ret = 0;
- /* In strict C standards conformance mode, consider unpredictable
- excess precision to mean lack of IEEE 754 support. The same
- applies to unpredictable contraction. For C++, and outside
- strict conformance mode, do not consider these options to mean
- lack of IEEE 754 support. */
+ /* In strict C standards conformance mode, consider a back-end providing
+ more implicit excess precision than the explicit excess precision
+ the front-end options would require to mean a lack of IEEE 754
+ support. For C++, and outside strict conformance mode, do not consider
+ this to mean a lack of IEEE 754 support. */
+
if (flag_iso
&& !c_dialect_cxx ()
- && TARGET_FLT_EVAL_METHOD != 0
- && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD)
+ && !c_cpp_flt_eval_method_iec_559 ())
ret = 0;
+
if (flag_iso
&& !c_dialect_cxx ()
&& flag_fp_contract_mode == FP_CONTRACT_FAST)
/* For stddef.h. They require macros defined in c-common.c. */
c_stddef_cpp_builtins ();
- /* Set include test macros for all C/C++ (not for just C++11 etc.)
- The builtins __has_include__ and __has_include_next__ are defined
- in libcpp. */
- cpp_define (pfile, "__has_include(STR)=__has_include__(STR)");
- cpp_define (pfile, "__has_include_next(STR)=__has_include_next__(STR)");
-
if (c_dialect_cxx ())
{
if (flag_weak && SUPPORTS_ONE_ONLY)
if (flag_rtti)
{
cpp_define (pfile, "__GXX_RTTI");
- cpp_define (pfile, "__cpp_rtti=199711");
+ cpp_define (pfile, "__cpp_rtti=199711L");
}
if (cxx_dialect >= cxx11)
/* Binary literals have been allowed in g++ before C++11
and were standardized for C++14. */
if (!pedantic || cxx_dialect > cxx11)
- cpp_define (pfile, "__cpp_binary_literals=201304");
+ cpp_define (pfile, "__cpp_binary_literals=201304L");
+
+ /* Similarly for hexadecimal floating point literals and C++17. */
+ if (!pedantic || cpp_get_options (parse_in)->extended_numbers)
+ cpp_define (pfile, "__cpp_hex_float=201603L");
/* Arrays of runtime bound were removed from C++14, but we still
support GNU VLAs. Let's define this macro to a low number
complain about use of VLAs. */
if (c_dialect_cxx ()
&& (pedantic ? warn_vla == 0 : warn_vla <= 0))
- cpp_define (pfile, "__cpp_runtime_arrays=198712");
+ cpp_define (pfile, "__cpp_runtime_arrays=198712L");
if (cxx_dialect >= cxx11)
{
/* Set feature test macros for C++11. */
if (cxx_dialect <= cxx14)
- cpp_define (pfile, "__cpp_unicode_characters=200704");
- cpp_define (pfile, "__cpp_raw_strings=200710");
- cpp_define (pfile, "__cpp_unicode_literals=200710");
- cpp_define (pfile, "__cpp_user_defined_literals=200809");
- cpp_define (pfile, "__cpp_lambdas=200907");
+ cpp_define (pfile, "__cpp_unicode_characters=200704L");
+ cpp_define (pfile, "__cpp_raw_strings=200710L");
+ cpp_define (pfile, "__cpp_unicode_literals=200710L");
+ cpp_define (pfile, "__cpp_user_defined_literals=200809L");
+ cpp_define (pfile, "__cpp_lambdas=200907L");
if (cxx_dialect == cxx11)
- cpp_define (pfile, "__cpp_constexpr=200704");
- cpp_define (pfile, "__cpp_range_based_for=200907");
+ cpp_define (pfile, "__cpp_constexpr=200704L");
+ if (cxx_dialect <= cxx14)
+ cpp_define (pfile, "__cpp_range_based_for=200907L");
if (cxx_dialect <= cxx14)
- cpp_define (pfile, "__cpp_static_assert=200410");
- cpp_define (pfile, "__cpp_decltype=200707");
- cpp_define (pfile, "__cpp_attributes=200809");
- cpp_define (pfile, "__cpp_rvalue_reference=200610");
- cpp_define (pfile, "__cpp_variadic_templates=200704");
- cpp_define (pfile, "__cpp_initializer_lists=200806");
- cpp_define (pfile, "__cpp_delegating_constructors=200604");
- cpp_define (pfile, "__cpp_nsdmi=200809");
- cpp_define (pfile, "__cpp_inheriting_constructors=200802");
- cpp_define (pfile, "__cpp_ref_qualifiers=200710");
- cpp_define (pfile, "__cpp_alias_templates=200704");
+ cpp_define (pfile, "__cpp_static_assert=200410L");
+ cpp_define (pfile, "__cpp_decltype=200707L");
+ cpp_define (pfile, "__cpp_attributes=200809L");
+ cpp_define (pfile, "__cpp_rvalue_reference=200610L");
+ cpp_define (pfile, "__cpp_rvalue_references=200610L");
+ cpp_define (pfile, "__cpp_variadic_templates=200704L");
+ cpp_define (pfile, "__cpp_initializer_lists=200806L");
+ cpp_define (pfile, "__cpp_delegating_constructors=200604L");
+ cpp_define (pfile, "__cpp_nsdmi=200809L");
+ if (!flag_new_inheriting_ctors)
+ cpp_define (pfile, "__cpp_inheriting_constructors=200802L");
+ else
+ cpp_define (pfile, "__cpp_inheriting_constructors=201511L");
+ cpp_define (pfile, "__cpp_ref_qualifiers=200710L");
+ cpp_define (pfile, "__cpp_alias_templates=200704L");
}
if (cxx_dialect > cxx11)
{
/* Set feature test macros for C++14. */
- cpp_define (pfile, "__cpp_return_type_deduction=201304");
- cpp_define (pfile, "__cpp_init_captures=201304");
- cpp_define (pfile, "__cpp_generic_lambdas=201304");
- cpp_define (pfile, "__cpp_constexpr=201304");
- cpp_define (pfile, "__cpp_decltype_auto=201304");
- cpp_define (pfile, "__cpp_aggregate_nsdmi=201304");
- cpp_define (pfile, "__cpp_variable_templates=201304");
- cpp_define (pfile, "__cpp_digit_separators=201309");
+ cpp_define (pfile, "__cpp_return_type_deduction=201304L");
+ if (cxx_dialect <= cxx17)
+ {
+ cpp_define (pfile, "__cpp_init_captures=201304L");
+ cpp_define (pfile, "__cpp_generic_lambdas=201304L");
+ }
+ if (cxx_dialect <= cxx14)
+ cpp_define (pfile, "__cpp_constexpr=201304L");
+ cpp_define (pfile, "__cpp_decltype_auto=201304L");
+ cpp_define (pfile, "__cpp_aggregate_nsdmi=201304L");
+ cpp_define (pfile, "__cpp_variable_templates=201304L");
+ cpp_define (pfile, "__cpp_digit_separators=201309L");
}
if (cxx_dialect > cxx14)
{
- /* Set feature test macros for C++1z. */
- cpp_define (pfile, "__cpp_unicode_characters=201411");
- cpp_define (pfile, "__cpp_static_assert=201411");
- cpp_define (pfile, "__cpp_namespace_attributes=201411");
- cpp_define (pfile, "__cpp_enumerator_attributes=201411");
- cpp_define (pfile, "__cpp_nested_namespace_definitions=201411");
- cpp_define (pfile, "__cpp_fold_expressions=201411");
- cpp_define (pfile, "__cpp_nontype_template_args=201411");
+ /* Set feature test macros for C++17. */
+ cpp_define (pfile, "__cpp_unicode_characters=201411L");
+ cpp_define (pfile, "__cpp_static_assert=201411L");
+ cpp_define (pfile, "__cpp_namespace_attributes=201411L");
+ cpp_define (pfile, "__cpp_enumerator_attributes=201411L");
+ cpp_define (pfile, "__cpp_nested_namespace_definitions=201411L");
+ cpp_define (pfile, "__cpp_fold_expressions=201603L");
+ cpp_define (pfile, "__cpp_nontype_template_args=201411L");
+ cpp_define (pfile, "__cpp_range_based_for=201603L");
+ if (cxx_dialect <= cxx17)
+ cpp_define (pfile, "__cpp_constexpr=201603L");
+ cpp_define (pfile, "__cpp_if_constexpr=201606L");
+ cpp_define (pfile, "__cpp_capture_star_this=201603L");
+ cpp_define (pfile, "__cpp_inline_variables=201606L");
+ cpp_define (pfile, "__cpp_aggregate_bases=201603L");
+ if (cxx_dialect <= cxx17)
+ cpp_define (pfile, "__cpp_deduction_guides=201703L");
+ cpp_define (pfile, "__cpp_noexcept_function_type=201510L");
+ /* Old macro, superseded by
+ __cpp_nontype_template_parameter_auto. */
+ cpp_define (pfile, "__cpp_template_auto=201606L");
+ cpp_define (pfile, "__cpp_structured_bindings=201606L");
+ cpp_define (pfile, "__cpp_variadic_using=201611L");
+ cpp_define (pfile, "__cpp_guaranteed_copy_elision=201606L");
+ cpp_define (pfile, "__cpp_nontype_template_parameter_auto=201606L");
+ }
+ if (cxx_dialect > cxx17)
+ {
+ /* Set feature test macros for C++2a. */
+ cpp_define (pfile, "__cpp_init_captures=201803L");
+ cpp_define (pfile, "__cpp_generic_lambdas=201707L");
+ cpp_define (pfile, "__cpp_designated_initializers=201707L");
+ cpp_define (pfile, "__cpp_constexpr=201907L");
+ cpp_define (pfile, "__cpp_constexpr_in_decltype=201711L");
+ cpp_define (pfile, "__cpp_conditional_explicit=201806L");
+ /* cpp_define (pfile, "__cpp_consteval=201811L"); */
+ cpp_define (pfile, "__cpp_constinit=201907L");
+ cpp_define (pfile, "__cpp_deduction_guides=201907L");
+ cpp_define (pfile, "__cpp_nontype_template_parameter_class=201806L");
+ cpp_define (pfile, "__cpp_impl_destroying_delete=201806L");
+ cpp_define (pfile, "__cpp_constexpr_dynamic_alloc=201907L");
+ cpp_define (pfile, "__cpp_impl_three_way_comparison=201907L");
+ cpp_define (pfile, "__cpp_aggregate_paren_init=201902L");
}
if (flag_concepts)
- /* Use a value smaller than the 201507 specified in
- the TS, since we don't yet support extended auto. */
- cpp_define (pfile, "__cpp_concepts=201500");
+ {
+ if (cxx_dialect >= cxx2a)
+ cpp_define (pfile, "__cpp_concepts=201907L");
+ else
+ cpp_define (pfile, "__cpp_concepts=201507L");
+ }
+ if (flag_coroutines)
+ cpp_define (pfile, "__cpp_coroutines=201902L"); /* n4835, C++20 CD */
if (flag_tm)
/* Use a value smaller than the 201505 specified in
the TS, since we don't yet support atomic_cancel. */
- cpp_define (pfile, "__cpp_transactional_memory=210500");
+ cpp_define (pfile, "__cpp_transactional_memory=201500L");
if (flag_sized_deallocation)
- cpp_define (pfile, "__cpp_sized_deallocation=201309");
+ cpp_define (pfile, "__cpp_sized_deallocation=201309L");
+ if (aligned_new_threshold)
+ {
+ cpp_define (pfile, "__cpp_aligned_new=201606L");
+ cpp_define_formatted (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__=%d",
+ aligned_new_threshold);
+ }
+ if (flag_new_ttp)
+ cpp_define (pfile, "__cpp_template_template_args=201611L");
+ if (flag_threadsafe_statics)
+ cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
+ if (flag_char8_t)
+ cpp_define (pfile, "__cpp_char8_t=201811L");
}
/* Note that we define this for C as well, so that we know if
__attribute__((cleanup)) will interface with EH. */
{
cpp_define (pfile, "__EXCEPTIONS");
if (c_dialect_cxx ())
- cpp_define (pfile, "__cpp_exceptions=199711");
+ cpp_define (pfile, "__cpp_exceptions=199711L");
}
/* Represents the C++ ABI version, always defined so it can be used while
builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node);
builtin_define_type_max ("__SIZE_MAX__", size_type_node);
+ /* These are needed for TS 18661-1. */
+ builtin_define_type_width ("__SCHAR_WIDTH__", signed_char_type_node,
+ unsigned_char_type_node);
+ builtin_define_type_width ("__SHRT_WIDTH__", short_integer_type_node,
+ short_unsigned_type_node);
+ builtin_define_type_width ("__INT_WIDTH__", integer_type_node,
+ unsigned_type_node);
+ builtin_define_type_width ("__LONG_WIDTH__", long_integer_type_node,
+ long_unsigned_type_node);
+ builtin_define_type_width ("__LONG_LONG_WIDTH__",
+ long_long_integer_type_node,
+ long_long_unsigned_type_node);
+ builtin_define_type_width ("__WCHAR_WIDTH__", underlying_wchar_type_node,
+ NULL_TREE);
+ builtin_define_type_width ("__WINT_WIDTH__", wint_type_node, NULL_TREE);
+ builtin_define_type_width ("__PTRDIFF_WIDTH__", ptrdiff_type_node, NULL_TREE);
+ builtin_define_type_width ("__SIZE_WIDTH__", size_type_node, NULL_TREE);
+
if (c_dialect_cxx ())
for (i = 0; i < NUM_INT_N_ENTS; i ++)
if (int_n_enabled_p[i])
builtin_define_with_int_value ("__GCC_IEC_559_COMPLEX",
cpp_iec_559_complex_value ());
- /* float.h needs to know this. */
+ /* float.h needs these to correctly set FLT_EVAL_METHOD
+
+ We define two values:
+
+ __FLT_EVAL_METHOD__
+ Which, depending on the value given for
+ -fpermitted-flt-eval-methods, may be limited to only those values
+ for FLT_EVAL_METHOD defined in C99/C11.
+
+ __FLT_EVAL_METHOD_TS_18661_3__
+ Which always permits the values for FLT_EVAL_METHOD defined in
+ ISO/IEC TS 18661-3. */
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
- TARGET_FLT_EVAL_METHOD);
+ c_flt_eval_method (true));
+ builtin_define_with_int_value ("__FLT_EVAL_METHOD_TS_18661_3__",
+ c_flt_eval_method (false));
/* And decfloat.h needs this. */
builtin_define_with_int_value ("__DEC_EVAL_METHOD__",
builtin_define_float_constants ("LDBL", "L", "%s", "L",
long_double_type_node);
- /* For decfloat.h. */
- builtin_define_decimal_float_constants ("DEC32", "DF", dfloat32_type_node);
- builtin_define_decimal_float_constants ("DEC64", "DD", dfloat64_type_node);
- builtin_define_decimal_float_constants ("DEC128", "DL", dfloat128_type_node);
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ {
+ if (FLOATN_NX_TYPE_NODE (i) == NULL_TREE)
+ continue;
+ char prefix[20], csuffix[20];
+ sprintf (prefix, "FLT%d%s", floatn_nx_types[i].n,
+ floatn_nx_types[i].extended ? "X" : "");
+ sprintf (csuffix, "F%d%s", floatn_nx_types[i].n,
+ floatn_nx_types[i].extended ? "x" : "");
+ builtin_define_float_constants (prefix, ggc_strdup (csuffix), "%s",
+ csuffix, FLOATN_NX_TYPE_NODE (i));
+ }
+
+ /* For float.h. */
+ if (targetm.decimal_float_supported_p ())
+ {
+ builtin_define_decimal_float_constants ("DEC32", "DF",
+ dfloat32_type_node);
+ builtin_define_decimal_float_constants ("DEC64", "DD",
+ dfloat64_type_node);
+ builtin_define_decimal_float_constants ("DEC128", "DL",
+ dfloat128_type_node);
+ }
/* For fixed-point fibt, ibit, max, min, and epsilon. */
if (targetm.fixed_point_supported_p ())
if (flag_building_libgcc)
{
/* Properties of floating-point modes for libgcc2.c. */
- for (machine_mode mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ opt_scalar_float_mode mode_iter;
+ FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
{
+ scalar_float_mode mode = mode_iter.require ();
const char *name = GET_MODE_NAME (mode);
char *macro_name
= (char *) alloca (strlen (name)
macro_name = (char *) alloca (strlen (name)
+ sizeof ("__LIBGCC__FUNC_EXT__"));
sprintf (macro_name, "__LIBGCC_%s_FUNC_EXT__", name);
- const char *suffix;
+ char suffix[20] = "";
if (mode == TYPE_MODE (double_type_node))
- suffix = "";
+ ; /* Empty suffix correct. */
else if (mode == TYPE_MODE (float_type_node))
- suffix = "f";
+ suffix[0] = 'f';
else if (mode == TYPE_MODE (long_double_type_node))
- suffix = "l";
- /* ??? The following assumes the built-in functions (defined
- in target-specific code) match the suffixes used for
- constants. Because in fact such functions are not
- defined for the 'w' suffix, 'l' is used there
- instead. */
- else if (mode == targetm.c.mode_for_suffix ('q'))
- suffix = "q";
- else if (mode == targetm.c.mode_for_suffix ('w'))
- suffix = "l";
+ suffix[0] = 'l';
else
- gcc_unreachable ();
+ {
+ bool found_suffix = false;
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ if (FLOATN_NX_TYPE_NODE (i) != NULL_TREE
+ && mode == TYPE_MODE (FLOATN_NX_TYPE_NODE (i)))
+ {
+ sprintf (suffix, "f%d%s", floatn_nx_types[i].n,
+ floatn_nx_types[i].extended ? "x" : "");
+ found_suffix = true;
+ break;
+ }
+ gcc_assert (found_suffix);
+ }
builtin_define_with_value (macro_name, suffix, 0);
+
+ /* The way __LIBGCC_*_EXCESS_PRECISION__ is used is about
+ eliminating excess precision from results assigned to
+ variables - meaning it should be about the implicit excess
+ precision only. */
bool excess_precision = false;
- if (TARGET_FLT_EVAL_METHOD != 0
- && mode != TYPE_MODE (long_double_type_node)
- && (mode == TYPE_MODE (float_type_node)
- || mode == TYPE_MODE (double_type_node)))
- switch (TARGET_FLT_EVAL_METHOD)
- {
- case -1:
- case 2:
- excess_precision = true;
- break;
-
- case 1:
- excess_precision = mode == TYPE_MODE (float_type_node);
- break;
-
- default:
- gcc_unreachable ();
- }
+ machine_mode float16_type_mode = (float16_type_node
+ ? TYPE_MODE (float16_type_node)
+ : VOIDmode);
+ switch (targetm.c.excess_precision
+ (EXCESS_PRECISION_TYPE_IMPLICIT))
+ {
+ case FLT_EVAL_METHOD_UNPREDICTABLE:
+ case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE:
+ excess_precision = (mode == float16_type_mode
+ || mode == TYPE_MODE (float_type_node)
+ || mode == TYPE_MODE (double_type_node));
+ break;
+
+ case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE:
+ excess_precision = (mode == float16_type_mode
+ || mode == TYPE_MODE (float_type_node));
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT:
+ excess_precision = mode == float16_type_mode;
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16:
+ excess_precision = false;
+ break;
+ default:
+ gcc_unreachable ();
+ }
macro_name = (char *) alloca (strlen (name)
+ sizeof ("__LIBGCC__EXCESS_"
"PRECISION__"));
builtin_define_with_value ("__LIBGCC_EH_FRAME_SECTION_NAME__",
EH_FRAME_SECTION_NAME, 1);
#endif
-#ifdef JCR_SECTION_NAME
- builtin_define_with_value ("__LIBGCC_JCR_SECTION_NAME__",
- JCR_SECTION_NAME, 1);
-#endif
#ifdef CTORS_SECTION_ASM_OP
builtin_define_with_value ("__LIBGCC_CTORS_SECTION_ASM_OP__",
CTORS_SECTION_ASM_OP, 1);
cpp_define (pfile, "__WCHAR_UNSIGNED__");
cpp_atomic_builtins (pfile);
-
+
+ /* Show support for __builtin_speculation_safe_value () if the target
+ has been updated to fully support it. */
+ if (targetm.have_speculation_safe_value (false))
+ cpp_define (pfile, "__HAVE_SPECULATION_SAFE_VALUE");
+
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_cfi_asm ())
cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM");
cpp_define (pfile, "__SSP__=1");
if (flag_openacc)
- cpp_define (pfile, "_OPENACC=201306");
+ cpp_define (pfile, "_OPENACC=201711");
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201511");
struct GTY(()) lazy_hex_fp_value_struct
{
const char *hex_str;
- cpp_macro *macro;
machine_mode mode;
int digits;
const char *fp_suffix;
};
-static GTY(()) struct lazy_hex_fp_value_struct lazy_hex_fp_values[12];
-static GTY(()) int lazy_hex_fp_value_count;
+/* Number of the expensive to compute macros we should evaluate lazily.
+ Each builtin_define_float_constants invocation calls
+ builtin_define_with_hex_fp_value 5 times and builtin_define_float_constants
+ is called for FLT, DBL, LDBL and up to NUM_FLOATN_NX_TYPES times for
+ FLTNN*. */
+#define LAZY_HEX_FP_VALUES_CNT (5 * (3 + NUM_FLOATN_NX_TYPES))
+static GTY(()) struct lazy_hex_fp_value_struct
+ lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT];
+static GTY(()) unsigned lazy_hex_fp_value_count;
-static bool
-lazy_hex_fp_value (cpp_reader *pfile ATTRIBUTE_UNUSED,
- cpp_hashnode *node)
+static void
+lazy_hex_fp_value (cpp_reader *, cpp_macro *macro, unsigned num)
{
REAL_VALUE_TYPE real;
char dec_str[64], buf1[256];
- unsigned int idx;
- if (node->value.builtin < BT_FIRST_USER
- || (int) node->value.builtin >= BT_FIRST_USER + lazy_hex_fp_value_count)
- return false;
- idx = node->value.builtin - BT_FIRST_USER;
- real_from_string (&real, lazy_hex_fp_values[idx].hex_str);
+ gcc_checking_assert (num < lazy_hex_fp_value_count);
+
+ real_from_string (&real, lazy_hex_fp_values[num].hex_str);
real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str),
- lazy_hex_fp_values[idx].digits, 0,
- lazy_hex_fp_values[idx].mode);
-
- sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[idx].fp_suffix);
- node->flags &= ~(NODE_BUILTIN | NODE_USED);
- node->value.macro = lazy_hex_fp_values[idx].macro;
- for (idx = 0; idx < node->value.macro->count; idx++)
- if (node->value.macro->exp.tokens[idx].type == CPP_NUMBER)
- break;
- gcc_assert (idx < node->value.macro->count);
- node->value.macro->exp.tokens[idx].val.str.len = strlen (buf1);
- node->value.macro->exp.tokens[idx].val.str.text
- = (const unsigned char *) ggc_strdup (buf1);
- return true;
+ lazy_hex_fp_values[num].digits, 0,
+ lazy_hex_fp_values[num].mode);
+
+ size_t len
+ = sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[num].fp_suffix);
+ gcc_assert (len < sizeof (buf1));
+ for (unsigned idx = 0; idx < macro->count; idx++)
+ if (macro->exp.tokens[idx].type == CPP_NUMBER)
+ {
+ macro->exp.tokens[idx].val.str.len = len;
+ macro->exp.tokens[idx].val.str.text
+ = (const unsigned char *) ggc_strdup (buf1);
+ return;
+ }
+
+ /* We must have replaced a token. */
+ gcc_unreachable ();
}
/* Pass an object-like macro a hexadecimal floating-point value. */
const char *fp_cast)
{
REAL_VALUE_TYPE real;
- char dec_str[64], buf1[256], buf2[256];
+ char dec_str[64], buf[256], buf1[128], buf2[64];
/* This is very expensive, so if possible expand them lazily. */
- if (lazy_hex_fp_value_count < 12
+ if (lazy_hex_fp_value_count < LAZY_HEX_FP_VALUES_CNT
&& flag_dump_macros == 0
+ && flag_dump_go_spec == NULL
&& !cpp_get_options (parse_in)->traditional)
{
- struct cpp_hashnode *node;
if (lazy_hex_fp_value_count == 0)
- cpp_get_callbacks (parse_in)->user_builtin_macro = lazy_hex_fp_value;
+ cpp_get_callbacks (parse_in)->user_lazy_macro = lazy_hex_fp_value;
sprintf (buf2, fp_cast, "1.1");
sprintf (buf1, "%s=%s", macro, buf2);
cpp_define (parse_in, buf1);
- node = C_CPP_HASHNODE (get_identifier (macro));
+ struct cpp_hashnode *node = C_CPP_HASHNODE (get_identifier (macro));
lazy_hex_fp_values[lazy_hex_fp_value_count].hex_str
= ggc_strdup (hex_str);
lazy_hex_fp_values[lazy_hex_fp_value_count].mode = TYPE_MODE (type);
lazy_hex_fp_values[lazy_hex_fp_value_count].digits = digits;
lazy_hex_fp_values[lazy_hex_fp_value_count].fp_suffix = fp_suffix;
- lazy_hex_fp_values[lazy_hex_fp_value_count].macro = node->value.macro;
- node->flags |= NODE_BUILTIN;
- node->value.builtin
- = (enum cpp_builtin_type) (BT_FIRST_USER + lazy_hex_fp_value_count);
- lazy_hex_fp_value_count++;
+ cpp_define_lazily (parse_in, node, lazy_hex_fp_value_count++);
return;
}
/* Assemble the macro in the following fashion
macro = fp_cast [dec_str fp_suffix] */
- sprintf (buf1, "%s%s", dec_str, fp_suffix);
- sprintf (buf2, fp_cast, buf1);
- sprintf (buf1, "%s=%s", macro, buf2);
+ sprintf (buf2, "%s%s", dec_str, fp_suffix);
+ sprintf (buf1, fp_cast, buf2);
+ sprintf (buf, "%s=%s", macro, buf1);
- cpp_define (parse_in, buf1);
+ cpp_define (parse_in, buf);
}
/* Return a string constant for the suffix for a value of type TYPE
}
}
+/* Define WIDTH_MACRO for the width of TYPE. If TYPE2 is not NULL,
+ both types must have the same width. */
+
+static void
+builtin_define_type_width (const char *width_macro, tree type, tree type2)
+{
+ if (type2 != NULL_TREE)
+ gcc_assert (TYPE_PRECISION (type) == TYPE_PRECISION (type2));
+ builtin_define_with_int_value (width_macro, TYPE_PRECISION (type));
+}
+
#include "gt-c-family-c-cppbuiltin.h"