DEF_PRIMITIVE_TYPE (BT_DFLOAT128, (dfloat128_type_node
? dfloat128_type_node
: error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT64X, (dfloat64x_type_node
+ ? dfloat64x_type_node
+ : error_mark_node))
DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT32, BT_DFLOAT32)
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT64, BT_DFLOAT64)
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT128, BT_DFLOAT128)
+DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT64X, BT_DFLOAT64X)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_CONST_STRING, BT_DFLOAT64, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_CONST_STRING,
BT_DFLOAT128, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64X_CONST_STRING, BT_DFLOAT64X,
+ BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_UNWINDWORD_PTR, BT_UNWINDWORD, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_WINT, BT_INT, BT_WINT)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_DFLOAT32, BT_DFLOAT32, BT_DFLOAT32)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_DFLOAT64, BT_DFLOAT64, BT_DFLOAT64)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_DFLOAT128, BT_DFLOAT128, BT_DFLOAT128)
+DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64X_DFLOAT64X, BT_DFLOAT64X, BT_DFLOAT64X)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_CONST_PTR, BT_VOID, BT_CONST_PTR)
case BUILT_IN_FABSD32:
case BUILT_IN_FABSD64:
case BUILT_IN_FABSD128:
+ case BUILT_IN_FABSD64X:
target = expand_builtin_fabs (exp, target, subtarget);
if (target)
return target;
case BUILT_IN_INFD32:
case BUILT_IN_INFD64:
case BUILT_IN_INFD128:
+ case BUILT_IN_INFD64X:
return fold_builtin_inf (loc, type, true);
CASE_FLT_FN (BUILT_IN_HUGE_VAL):
case BUILT_IN_FABSD32:
case BUILT_IN_FABSD64:
case BUILT_IN_FABSD128:
+ case BUILT_IN_FABSD64X:
return fold_builtin_fabs (loc, arg0, type);
case BUILT_IN_ABS:
DEF_C23_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C23_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C23_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C23_BUILTIN (BUILT_IN_FABSD64X, "fabsd64x", BT_FN_DFLOAT64X_DFLOAT64X, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_INFD64X, "infd64x", BT_FN_DFLOAT64X, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_IRINT, "irint", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_GCC_BUILTIN (BUILT_IN_IRINTF, "irintf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_GCC_BUILTIN (BUILT_IN_IRINTL, "irintl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C23_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_C23_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_C23_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
+DEF_C23_BUILTIN (BUILT_IN_NAND64X, "nand64x", BT_FN_DFLOAT64X_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANSD32, "nansd32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANSD64, "nansd64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANSD128, "nansd128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
+DEF_GCC_BUILTIN (BUILT_IN_NANSD64X, "nansd64x", BT_FN_DFLOAT64X_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
tree dfloat32_type_node;
tree dfloat64_type_node;
- tree_dfloat128_type_node;
+ tree dfloat128_type_node;
+ tree dfloat64x_type_node;
tree intQI_type_node;
tree intHI_type_node;
{ "_Decimal32", RID_DFLOAT32, D_CONLY },
{ "_Decimal64", RID_DFLOAT64, D_CONLY },
{ "_Decimal128", RID_DFLOAT128, D_CONLY },
+ { "_Decimal64x", RID_DFLOAT64X, D_CONLY },
{ "_Fract", RID_FRACT, D_CONLY | D_EXT },
{ "_Accum", RID_ACCUM, D_CONLY | D_EXT },
{ "_Sat", RID_SAT, D_CONLY | D_EXT },
record_builtin_type (RID_DFLOAT32, NULL, dfloat32_type_node);
record_builtin_type (RID_DFLOAT64, NULL, dfloat64_type_node);
record_builtin_type (RID_DFLOAT128, NULL, dfloat128_type_node);
+ record_builtin_type (RID_DFLOAT64X, NULL, dfloat64x_type_node);
}
if (targetm.fixed_point_supported_p ())
RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH,
RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, RID_BUILTIN_STDC,
RID_BUILTIN_COUNTED_BY_REF,
- RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
+ RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, RID_DFLOAT64X,
/* TS 18661-3 keywords, in the same sequence as the TI_* values. */
RID_FLOAT16,
dfloat64_type_node);
builtin_define_decimal_float_constants ("DEC128", "DL",
dfloat128_type_node);
+ if (dfloat64x_type_node)
+ builtin_define_decimal_float_constants ("DEC64X", "D64x",
+ dfloat64x_type_node);
}
/* For fixed-point fibt, ibit, max, min, and epsilon. */
type = dfloat128_type_node;
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
type = dfloat32_type_node;
+ else if ((flags & CPP_N_FLOATNX) != 0)
+ type = dfloat64x_type_node;
else
type = dfloat64_type_node;
else
{
if (ISDIGIT (token->val.str.text[copylen - 1]))
copylen -= (flags & CPP_N_LARGE) ? 4 : 3;
+ else if ((flags & CPP_N_FLOATNX) != 0)
+ copylen -= 4;
else
copylen -= 2;
}
pp_string (pp, "dd");
else if (TREE_TYPE (r) == dfloat32_type_node)
pp_string (pp, "df");
+ else if (TREE_TYPE (r) == dfloat64x_type_node)
+ pp_string (pp, "d64x");
else if (TREE_TYPE (r) != double_type_node)
for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
if (TREE_TYPE (r) == FLOATN_NX_TYPE_NODE (i))
error_at (loc,
("both %<long%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<long%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else
{
specs->long_p = true;
error_at (loc,
("both %<short%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<short%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else
{
specs->short_p = true;
error_at (loc,
("both %<signed%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<signed%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else
{
specs->signed_p = true;
error_at (loc,
("both %<unsigned%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<unsigned%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else
{
specs->unsigned_p = true;
error_at (loc,
("both %<complex%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<complex%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_fract)
error_at (loc,
("both %<complex%> and %<_Fract%> in "
error_at (loc,
("both %<_Sat%> and %<_Decimal128%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_dfloat64x)
+ error_at (loc,
+ ("both %<_Sat%> and %<_Decimal64x%> in "
+ "declaration specifiers"));
else if (specs->complex_p)
error_at (loc,
("both %<_Sat%> and %<complex%> in "
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
+ case RID_DFLOAT64X:
{
const char *str;
if (i == RID_DFLOAT32)
str = "_Decimal32";
else if (i == RID_DFLOAT64)
str = "_Decimal64";
- else
+ else if (i == RID_DFLOAT128)
str = "_Decimal128";
+ else
+ str = "_Decimal64x";
if (specs->long_long_p)
error_at (loc,
("both %<long long%> and %qs in "
specs->typespec_word = cts_dfloat32;
else if (i == RID_DFLOAT64)
specs->typespec_word = cts_dfloat64;
- else
+ else if (i == RID_DFLOAT128)
specs->typespec_word = cts_dfloat128;
+ else
+ specs->typespec_word = cts_dfloat64x;
specs->locations[cdw_typespec] = loc;
}
if (!targetm.decimal_float_supported_p ())
case cts_dfloat32:
case cts_dfloat64:
case cts_dfloat128:
+ case cts_dfloat64x:
gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
&& !specs->signed_p && !specs->unsigned_p && !specs->complex_p);
if (!targetm.decimal_float_supported_p ())
specs->type = dfloat32_type_node;
else if (specs->typespec_word == cts_dfloat64)
specs->type = dfloat64_type_node;
- else
+ else if (specs->typespec_word == cts_dfloat128)
specs->type = dfloat128_type_node;
+ else
+ specs->type = dfloat64x_type_node;
break;
case cts_fract:
gcc_assert (!specs->complex_p);
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
+ case RID_DFLOAT64X:
CASE_RID_FLOATN_NX:
case RID_BOOL:
case RID_BITINT:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
+ case RID_DFLOAT64X:
CASE_RID_FLOATN_NX:
case RID_BOOL:
case RID_BITINT:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
+ case RID_DFLOAT64X:
CASE_RID_FLOATN_NX:
case RID_BOOL:
case RID_FRACT:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
+ case RID_DFLOAT64X:
CASE_RID_FLOATN_NX:
case RID_BOOL:
case RID_BITINT:
bool arg_binary = all_binary;
bool arg_int_decimal = all_decimal;
bool arg_int_floatnx = false;
+ bool arg_int_decimalx = false;
for (unsigned int j = 1; j <= nargs; j++)
{
if (parm_kind[j] == tgmath_fixed)
arg_int_floatnx = true;
break;
}
+ if (rtype == dfloat64x_type_node)
+ arg_int_decimalx = true;
}
tree arg_real = NULL_TREE;
for (unsigned int j = 1; j <= nargs; j++)
if (TREE_CODE (type) == COMPLEX_TYPE)
type = TREE_TYPE (type);
if (INTEGRAL_TYPE_P (type))
- type = (arg_int_decimal
- ? dfloat64_type_node
+ type = (arg_int_decimalx
+ ? dfloat64x_type_node
: arg_int_floatnx
? float32x_type_node
+ : arg_int_decimal
+ ? dfloat64_type_node
: double_type_node);
if (arg_real == NULL_TREE)
arg_real = type;
case BUILT_IN_FABSD32:
case BUILT_IN_FABSD64:
case BUILT_IN_FABSD128:
+ case BUILT_IN_FABSD64X:
if (!DECIMAL_FLOAT_TYPE_P (atype))
{
if (INTEGRAL_TYPE_P (atype))
};
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
- "double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
- "_BitInt", or none of these. */
+ "double", "_Decimal32", "_Decimal64", "_Decimal128", "_Decimal64x",
+ "_Fract", "_Accum", "_BitInt", or none of these. */
enum c_typespec_keyword {
cts_none,
cts_void,
cts_dfloat32,
cts_dfloat64,
cts_dfloat128,
+ cts_dfloat64x,
cts_floatn_nx,
cts_fract,
cts_accum,
if (TYPE_MAIN_VARIANT (t1) == dfloat128_type_node
|| TYPE_MAIN_VARIANT (t2) == dfloat128_type_node)
return dfloat128_type_node;
+ /* And prefer _Decimal128 over _Decimal64x which has in GCC's
+ implementation the same mode. */
+ else if (TYPE_MAIN_VARIANT (t1) == dfloat64x_type_node
+ || TYPE_MAIN_VARIANT (t2) == dfloat64x_type_node)
+ return dfloat64x_type_node;
else if (TYPE_MAIN_VARIANT (t1) == dfloat64_type_node
|| TYPE_MAIN_VARIANT (t2) == dfloat64_type_node)
return dfloat64_type_node;
case CFN_BUILT_IN_NAND32:
case CFN_BUILT_IN_NAND64:
case CFN_BUILT_IN_NAND128:
+ case CFN_BUILT_IN_NAND64X:
return fold_const_builtin_nan (type, arg, true);
CASE_CFN_NANS:
case CFN_BUILT_IN_NANSD32:
case CFN_BUILT_IN_NANSD64:
case CFN_BUILT_IN_NANSD128:
+ case CFN_BUILT_IN_NANSD64X:
return fold_const_builtin_nan (type, arg, false);
case CFN_REDUC_PLUS:
#endif /* __STDC_WANT_IEC_60559_DFP_EXT__ || C23. */
+#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
+#undef DEC64X_MANT_DIG
+#define DEC64X_MANT_DIG __DEC64X_MANT_DIG__
+#undef DEC64X_MIN_EXP
+#define DEC64X_MIN_EXP __DEC64X_MIN_EXP__
+#undef DEC64X_MAX_EXP
+#define DEC64X_MAX_EXP __DEC64X_MAX_EXP__
+#undef DEC64X_MAX
+#define DEC64X_MAX __DEC64X_MAX__
+#undef DEC64X_EPSILON
+#define DEC64X_EPSILON __DEC64X_EPSILON__
+#undef DEC64X_MIN
+#define DEC64X_MIN __DEC64X_MIN__
+#undef DEC64X_TRUE_MIN
+#define DEC64X_TRUE_MIN __DEC64X_SUBNORMAL_MIN__
+#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */
+
#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
/* Infinity in type _Decimal32. */
#define DEC64_SNAN (__builtin_nansd64 (""))
#undef DEC128_SNAN
#define DEC128_SNAN (__builtin_nansd128 (""))
+#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
+#undef DEC64X_SNAN
+#define DEC64X_SNAN (__builtin_nansd64x (""))
+#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__ */
#endif /* C23 */
--- /dev/null
+/* Test that DFP constants and _Decimal64x keyword are diagnosed in C11 mode: -pedantic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic" } */
+
+int a = (int) 1.1D64x; /* { dg-warning "C23 feature" } */
+int b = (int) 2.d64x; /* { dg-warning "C23 feature" } */
+_Decimal64x c = 1; /* { dg-warning "ISO C does not support decimal floating-point before C23" } */
--- /dev/null
+/* Test that DFP constants and _Decimal64x keyword are diagnosed in C11 mode: -pedantic-errors. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int a = (int) 1.1D64x; /* { dg-error "C23 feature" } */
+int b = (int) 2.d64x; /* { dg-error "C23 feature" } */
+_Decimal64x c = 1; /* { dg-error "ISO C does not support decimal floating-point before C23" } */
--- /dev/null
+/* Test _Decimal64x in C23 mode. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a = (int) 1.1D64x;
+int b = (int) 2.d64x;
+_Decimal64x c = 1;
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+static_assert (expr_has_type (1.1D64x, _Decimal64x));
+static_assert (expr_has_type (2.d64x, _Decimal64x));
+static_assert (expr_has_type (.33D64x, _Decimal64x));
+static_assert (expr_has_type (2e1d64x, _Decimal64x));
+static_assert (expr_has_type (.3e2D64x, _Decimal64x));
+static_assert (expr_has_type (4.5e3d64x, _Decimal64x));
+static_assert (expr_has_type (5.e0D64x, _Decimal64x));
+static_assert (expr_has_type (1e+2d64x, _Decimal64x));
+static_assert (expr_has_type (1000e-3D64x, _Decimal64x));
+static_assert (expr_has_type (__DEC64X_MIN__, _Decimal64x));
+static_assert (expr_has_type (__DEC64X_MAX__, _Decimal64x));
+static_assert (expr_has_type (__DEC64X_EPSILON__, _Decimal64x));
+static_assert (expr_has_type (__DEC64X_SUBNORMAL_MIN__, _Decimal64x));
+#if __DEC64X_MANT_DIG__ == __DEC128_MANT_DIG__ \
+ && __DEC64X_MAX_EXP__ == __DEC128_MAX_EXP__
+static_assert (expr_has_type (1.1D32 + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1.1D64 + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1.1D128 + 1.1D64x, _Decimal128));
+static_assert (expr_has_type (1 + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1U + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1L + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1UL + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1LL + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1ULL + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1.1D32, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1.1D64, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1.1D64x, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1.1D128, _Decimal128));
+static_assert (expr_has_type (1.1D64x + 1, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1U, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1L, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1UL, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1LL, _Decimal64x));
+static_assert (expr_has_type (1.1D64x + 1ULL, _Decimal64x));
+#endif
+
+_Decimal64x
+foo (_Decimal64x x, _Decimal64x y)
+{
+ return x + y;
+}
+
+int
+main ()
+{
+#if __DEC64X_MANT_DIG__ == __DEC128_MANT_DIG__ \
+ && __DEC64X_MAX_EXP__ == __DEC128_MAX_EXP__
+ if (1.1D64x != 1.1dl
+ || 2.d64x != 2.dl
+ || .33D64x != .33dl
+ || 2e1d64x != 2e1dl
+ || .3e2D64x != .3e2dl
+ || 4.5e3d64x != 4.5e3dl
+ || 5.e0D64x != 5.e0dl
+ || 1e+2d64x != 1e+2dl
+ || 1000e-3D64x != 1000e-3dl
+ || __DEC64X_MIN__ != __DEC128_MIN__
+ || __DEC64X_MAX__ != __DEC128_MAX__
+ || __DEC64X_EPSILON__ != __DEC128_EPSILON__
+ || __DEC64X_SUBNORMAL_MIN__ != __DEC128_SUBNORMAL_MIN__
+ || foo (0.5d64x, 0.5D64x) != 1.D64x)
+ __builtin_abort ();
+#endif
+}
--- /dev/null
+/* Test that DFP constants and _Decimal64x keyword are accepted in C23 mode: compat warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -Wc11-c23-compat" } */
+
+int a = (int) 1.1D64x; /* { dg-warning "C23 feature" } */
+int b = (int) 2.d64x; /* { dg-warning "C23 feature" } */
+_Decimal64x c = 1; /* { dg-warning "ISO C does not support decimal floating-point before C23" } */
--- /dev/null
+/* Test _Decimal64x in C23 mode - builtins. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+_Decimal64x a = __builtin_infd64x ();
+_Decimal64x b = __builtin_nand64x ("");
+_Decimal64x c = __builtin_nansd64x ("");
+_Decimal64x d = -42.D64x;
+_Decimal64x e = 5.25d64x;
+
+int
+main ()
+{
+ if (__builtin_fabsd64x (-2.5d64x) != 2.5D64x
+ || __builtin_fabsd64x (42.25D64x) != 42.25d64x
+ || __builtin_fabsd64x (d) != 42.d64x
+ || __builtin_fabsd64x (e) != 5.25D64x
+ || __builtin_isinf (42.d64x)
+ || __builtin_isnan (0.d64x)
+ || !__builtin_isinf (__builtin_infd64x ())
+ || !__builtin_isnan (__builtin_nand64x (""))
+ /* || !__builtin_isinf (a) */
+ || !__builtin_isnan (b)
+ || !__builtin_isnan (c))
+ __builtin_abort ();
+}
--- /dev/null
+/* Test _Decimal64x in C23 mode - float.h macros. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#endif
+
+#include <float.h>
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+static_assert (expr_has_type (DEC64X_MAX, _Decimal64x));
+static_assert (expr_has_type (DEC64X_MIN, _Decimal64x));
+static_assert (expr_has_type (DEC64X_EPSILON, _Decimal64x));
+static_assert (expr_has_type (DEC64X_TRUE_MIN, _Decimal64x));
+
+int
+main ()
+{
+#if __DEC64X_MANT_DIG__ == __DEC128_MANT_DIG__ \
+ && __DEC64X_MAX_EXP__ == __DEC128_MAX_EXP__
+ if (DEC64X_MANT_DIG != 34)
+ __builtin_abort ();
+
+ if (DEC64X_MIN_EXP != -6142)
+ __builtin_abort ();
+
+ if (DEC64X_MAX_EXP != 6145)
+ __builtin_abort ();
+
+ if (DEC64X_MAX != 9.999999999999999999999999999999999E6144D64x)
+ __builtin_abort ();
+
+ if (DEC64X_EPSILON != 1E-33D64x)
+ __builtin_abort ();
+
+ if (DEC64X_MIN != 1E-6143D64x)
+ __builtin_abort ();
+
+ if (DEC64X_TRUE_MIN != 0.000000000000000000000000000000001E-6143D64x)
+ __builtin_abort ();
+#endif
+}
TI_DFLOAT32_TYPE,
TI_DFLOAT64_TYPE,
TI_DFLOAT128_TYPE,
+ TI_DFLOAT64X_TYPE,
TI_VOID_LIST_NODE,
TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
SET_TYPE_MODE (dfloat128_type_node, TDmode);
layout_type (dfloat128_type_node);
+
+ dfloat64x_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (dfloat64x_type_node) = DECIMAL128_TYPE_SIZE;
+ SET_TYPE_MODE (dfloat64x_type_node, TDmode);
+ layout_type (dfloat64x_type_node);
}
complex_integer_type_node = build_complex_type (integer_type_node, true);
#define dfloat32_type_node global_trees[TI_DFLOAT32_TYPE]
#define dfloat64_type_node global_trees[TI_DFLOAT64_TYPE]
#define dfloat128_type_node global_trees[TI_DFLOAT128_TYPE]
+#define dfloat64x_type_node global_trees[TI_DFLOAT64X_TYPE]
/* The fixed-point types. */
#define sat_short_fract_type_node global_trees[TI_SAT_SFRACT_TYPE]
df, DF, d32, D32 - _Decimal32.
dd, DD, d64, D64 - _Decimal64.
dl, DL, d128, D128 - _Decimal128.
-
- The dN and DN suffixes for _DecimalN, and dNx and DNx for
- _DecimalNx, defined in TS 18661-3:2015, are not supported.
+ d64x, D64x - _Decimal64x.
Fixed-point suffixes, from TR 18037:2008, are supported. They
consist of three parts, in order:
{
if (s[1] == '3' && s[2] == '2' && len == 2)
return CPP_N_DFLOAT | CPP_N_SMALL;
- if (s[1] == '6' && s[2] == '4' && len == 2)
- return CPP_N_DFLOAT | CPP_N_MEDIUM;
+ if (s[1] == '6' && s[2] == '4')
+ {
+ if (len == 2)
+ return CPP_N_DFLOAT | CPP_N_MEDIUM;
+ if (len == 3 && s[3] == 'x')
+ return CPP_N_DFLOAT | CPP_N_FLOATNX;
+ }
if (s[1] == '1' && s[2] == '2' && len == 3 && s[3] == '8')
return CPP_N_DFLOAT | CPP_N_LARGE;
}