target-def.h (TARGET_DECIMAL_FLOAT_SUPPORTED_P): New.

2005-12-16  Jon Grimm  <jgrimm2@us.ibm.com>
	    Janis Johnson  <janis187@us.ibm.com>
	    Ben Elliston  <bje@au.ibm.com>

	* target-def.h (TARGET_DECIMAL_FLOAT_SUPPORTED_P): New.
	(TARGET_INITIALIZER): Add TARGET_DECIMAL_FLOAT_P.
	* target.h (struct gcc_target): Add decimal_float_supported_p.
	* targhooks.c (default_scalar_mode_supported_p): Handle
	MODE_DECIMAL_FLOAT.
	* builtins.def: Add new builtins for 32, 64 and 128 bit variants
	of inf, nan, finite, isinf and isnan.
	* builtin-types.def (BT_DFLOAT32, BT_DFLOAT64, BT_DFLOAT128,
	BT_DFLOAT32_PTR, BT_DFLOAT64_PTR, BT_DFLOAT128_PTR,
	BT_FN_DFLOAT32, BT_FN_DFLOAT64, BT_FN_DFLOAT128,
	BT_FN_INT_DFLOAT32, BT_FN_INT_DFLOAT64, BT_FN_INT_DFLOAT128,
	BT_FN_DFLOAT32_CONST_STRING, BT_FN_DFLOAT64_CONST_STRING,
	BT_FN_DFLOAT32_CONST_STRING, BT_FN_DFLOAT32_DFLOAT32,
	BT_FN_DFLOAT64_DFLOAT64, BT_FN_DFLOAT128_DFLOAT128): New.
	* c-decl.c (declspecs_add_type): Verify combos on type qualifiers.
	Pedwarn if decimal floating point types are used.  Error if
	decimal floating point is not supported by the target.
	(finish_declspecs): Return type from DFP typespec_word.
	* c-typeck.c (c_common_type): Choose the decimal floating point
	type with the greater precision when determining a common type.
	(convert_arguments): Warn if there is a mismatch between argument
	and prototype for decimal float types.  Warn of conversions with
	binary float types and of precision narrowing due to prototype.
	* c-parser.c (reswords): Add _Decimal32, _Decimal64, _Decimal128.
	(c_token_starts_typename): Handle RID_DFLOAT32/64/128.
	(c_token_starts_declspecs): Likewise.
	(c_parser_attributes): Likewise.
	* c-common.h (enum rid): Add new enumeration values RID_DFLOAT32,
	RID_DFLOAT64, RID_DFLOAT128.
	(T_D32, TEX_D32, T_D64, TEX_D64, T_D128, TEX_D128): New macros.
	* c-common.c (c_common_type_for_mode): Handle decimal float modes.
	(shorten_compare): Convert DFP/BFP operands to a common type.
	(c_common_modes_and_builtins): Register built-in decimal float
	types if the target supports them.
	(handle_mode_addtribute): Handle MODE_DECIMAL_FLOAT.
	* builtins.c (fold_builtin_1): Handle 32, 64 and 128 bit cases of
	inf, nan, finite, isinf and isnan builtins.
	* c-cppbuiltin.c (builtin_define_decimal_float_constants): New.
	(builtin_define_float_constants): Assert non-decimal radix.
	(c_cpp_builtins): Register built-in __DEC_EVAL_METHOD__ define.
	Call builtin_define_decimal_float_constants for each type.
	* c-lex.c (interpret_float): Decode decimal float types from CPP_N
	flags.  Use real_from_string3, which can handle binary or decimal
	floats.
	* c-tree.h (enum c_typespec_keyword): Add cts_dfloat32,
	cts_dfloat64, cts_dfloat128.
	* tree.c (build_common_tree_nodes_2): Add decimal float types.
	* tree.h (enum tree_index): Add new enumeration values
	TI_DFLOAT32_TYPE, TI_DFLOAT64_TYPE, TI_DFLOAT128_TYPE,
	TI_DFLOAT32_PTR_TYPE, TI_DFLOAT64_PTR_TYPE, TI_DFLOAT128_PTR_TYPE.
	(dfloat32_type_node): New macro.
	(dfloat64_type_node, dfloat128_type_node): Likewise.
	(dfloat32_ptr_type_node, dfloat64_ptr_type_node): Likewise.
	(dfloat128_ptr_type_node): Likewise.
	* c-pretty-print.c (pp_c_floating_constant): Append 32, 64 and 128
	bit decimal floating point types with "df", "dd" and "dl".
	* c-format.h (enum format_lengths): Add new enumeration values
	FMT_LEN_H, FMT_LEN_D and FMT_LEN_DD.
	* c-format.c (printf_length_specs, scanf_length_specs): Add
	entries for H, D, DD.
	(print_char_table, scan_char_table): Use new entries.
	(asm_fprintf_char_table, gcc_diag_char_table,
	gcc_cdiag_char_table, gcc_cxxdiag_char_table): Adjust for longer
	length arrays.
	* defaults.h (DECIMAL32_TYPE_SIZE): Define.
	(DECIMAL64_TYPE_SIZE): Likewise.
	(DECIMAL128_TYPE_SIZE): Likewise.
	(TARGET_DEC_EVAL_METHOD): Likewise.
	* doc/extend.texi (Decimal Float): New node.
	(Constructing Calls): Document decimal float built-ins.
	* doc/tm.texi: Document TARGET_DECIMAL_FLOAT_SUPPORTED_P hook.
	* Makefile.in (USER_H): Add $(srcdir)/ginclude/decfloat.h.
	* ginclude/decfloat.h: New file.

Co-Authored-By: Ben Elliston <bje@au.ibm.com>
Co-Authored-By: Janis Johnson <janis187@us.ibm.com>

From-SVN: r108629
This commit is contained in:
Jon Grimm 2005-12-16 06:38:26 +00:00 committed by Ben Elliston
parent 425de7399f
commit 9a8ce21f3b
25 changed files with 745 additions and 89 deletions

View File

@ -1,3 +1,81 @@
2005-12-16 Jon Grimm <jgrimm2@us.ibm.com>
Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
* target-def.h (TARGET_DECIMAL_FLOAT_SUPPORTED_P): New.
(TARGET_INITIALIZER): Add TARGET_DECIMAL_FLOAT_P.
* target.h (struct gcc_target): Add decimal_float_supported_p.
* targhooks.c (default_scalar_mode_supported_p): Handle
MODE_DECIMAL_FLOAT.
* builtins.def: Add new builtins for 32, 64 and 128 bit variants
of inf, nan, finite, isinf and isnan.
* builtin-types.def (BT_DFLOAT32, BT_DFLOAT64, BT_DFLOAT128,
BT_DFLOAT32_PTR, BT_DFLOAT64_PTR, BT_DFLOAT128_PTR,
BT_FN_DFLOAT32, BT_FN_DFLOAT64, BT_FN_DFLOAT128,
BT_FN_INT_DFLOAT32, BT_FN_INT_DFLOAT64, BT_FN_INT_DFLOAT128,
BT_FN_DFLOAT32_CONST_STRING, BT_FN_DFLOAT64_CONST_STRING,
BT_FN_DFLOAT32_CONST_STRING, BT_FN_DFLOAT32_DFLOAT32,
BT_FN_DFLOAT64_DFLOAT64, BT_FN_DFLOAT128_DFLOAT128): New.
* c-decl.c (declspecs_add_type): Verify combos on type qualifiers.
Pedwarn if decimal floating point types are used. Error if
decimal floating point is not supported by the target.
(finish_declspecs): Return type from DFP typespec_word.
* c-typeck.c (c_common_type): Choose the decimal floating point
type with the greater precision when determining a common type.
(convert_arguments): Warn if there is a mismatch between argument
and prototype for decimal float types. Warn of conversions with
binary float types and of precision narrowing due to prototype.
* c-parser.c (reswords): Add _Decimal32, _Decimal64, _Decimal128.
(c_token_starts_typename): Handle RID_DFLOAT32/64/128.
(c_token_starts_declspecs): Likewise.
(c_parser_attributes): Likewise.
* c-common.h (enum rid): Add new enumeration values RID_DFLOAT32,
RID_DFLOAT64, RID_DFLOAT128.
(T_D32, TEX_D32, T_D64, TEX_D64, T_D128, TEX_D128): New macros.
* c-common.c (c_common_type_for_mode): Handle decimal float modes.
(shorten_compare): Convert DFP/BFP operands to a common type.
(c_common_modes_and_builtins): Register built-in decimal float
types if the target supports them.
(handle_mode_addtribute): Handle MODE_DECIMAL_FLOAT.
* builtins.c (fold_builtin_1): Handle 32, 64 and 128 bit cases of
inf, nan, finite, isinf and isnan builtins.
* c-cppbuiltin.c (builtin_define_decimal_float_constants): New.
(builtin_define_float_constants): Assert non-decimal radix.
(c_cpp_builtins): Register built-in __DEC_EVAL_METHOD__ define.
Call builtin_define_decimal_float_constants for each type.
* c-lex.c (interpret_float): Decode decimal float types from CPP_N
flags. Use real_from_string3, which can handle binary or decimal
floats.
* c-tree.h (enum c_typespec_keyword): Add cts_dfloat32,
cts_dfloat64, cts_dfloat128.
* tree.c (build_common_tree_nodes_2): Add decimal float types.
* tree.h (enum tree_index): Add new enumeration values
TI_DFLOAT32_TYPE, TI_DFLOAT64_TYPE, TI_DFLOAT128_TYPE,
TI_DFLOAT32_PTR_TYPE, TI_DFLOAT64_PTR_TYPE, TI_DFLOAT128_PTR_TYPE.
(dfloat32_type_node): New macro.
(dfloat64_type_node, dfloat128_type_node): Likewise.
(dfloat32_ptr_type_node, dfloat64_ptr_type_node): Likewise.
(dfloat128_ptr_type_node): Likewise.
* c-pretty-print.c (pp_c_floating_constant): Append 32, 64 and 128
bit decimal floating point types with "df", "dd" and "dl".
* c-format.h (enum format_lengths): Add new enumeration values
FMT_LEN_H, FMT_LEN_D and FMT_LEN_DD.
* c-format.c (printf_length_specs, scanf_length_specs): Add
entries for H, D, DD.
(print_char_table, scan_char_table): Use new entries.
(asm_fprintf_char_table, gcc_diag_char_table,
gcc_cdiag_char_table, gcc_cxxdiag_char_table): Adjust for longer
length arrays.
* defaults.h (DECIMAL32_TYPE_SIZE): Define.
(DECIMAL64_TYPE_SIZE): Likewise.
(DECIMAL128_TYPE_SIZE): Likewise.
(TARGET_DEC_EVAL_METHOD): Likewise.
* doc/extend.texi (Decimal Float): New node.
(Constructing Calls): Document decimal float built-ins.
* doc/tm.texi: Document TARGET_DECIMAL_FLOAT_SUPPORTED_P hook.
* Makefile.in (USER_H): Add $(srcdir)/ginclude/decfloat.h.
* ginclude/decfloat.h: New file.
2005-12-16 Alan Modra <amodra@bigpond.net.au>
* reload.c (find_reloads): Fix comment typo.

View File

@ -312,7 +312,8 @@ INSTALL_HEADERS_DIR = @build_install_headers_dir@
# Header files that are made available under the same name
# to programs compiled with GCC.
USER_H = $(srcdir)/ginclude/float.h \
USER_H = $(srcdir)/ginclude/decfloat.h \
$(srcdir)/ginclude/float.h \
$(srcdir)/ginclude/iso646.h \
$(srcdir)/ginclude/stdarg.h \
$(srcdir)/ginclude/stdbool.h \

View File

@ -98,6 +98,13 @@ DEF_PRIMITIVE_TYPE (BT_WINT, wint_type_node)
DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT32, dfloat32_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT64, dfloat64_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT128, dfloat128_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, dfloat32_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, dfloat64_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, dfloat128_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
@ -118,6 +125,9 @@ DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
distinguish it from two types in sequence, "long" followed by
"double". */
DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
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_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
@ -152,6 +162,9 @@ DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_FLOAT, BT_INT, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DOUBLE, BT_INT, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT32, BT_INT, BT_DFLOAT32)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT64, BT_INT, BT_DFLOAT64)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT128, BT_INT, BT_DFLOAT128)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_FLOAT, BT_LONG, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE, BT_LONG, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONGDOUBLE, BT_LONG, BT_LONGDOUBLE)
@ -168,10 +181,17 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
BT_LONGDOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_CONST_STRING, BT_DFLOAT32, BT_CONST_STRING)
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_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_WINT, BT_INT, BT_WINT)
DEF_FUNCTION_TYPE_1 (BT_FN_WINT_WINT, BT_WINT, 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_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)

View File

@ -8593,12 +8593,18 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
return fold_builtin_powi (fndecl, arglist, type);
CASE_FLT_FN (BUILT_IN_INF):
case BUILT_IN_INFD32:
case BUILT_IN_INFD64:
case BUILT_IN_INFD128:
return fold_builtin_inf (type, true);
CASE_FLT_FN (BUILT_IN_HUGE_VAL):
return fold_builtin_inf (type, false);
CASE_FLT_FN (BUILT_IN_NAN):
case BUILT_IN_NAND32:
case BUILT_IN_NAND64:
case BUILT_IN_NAND128:
return fold_builtin_nan (arglist, type, true);
CASE_FLT_FN (BUILT_IN_NANS):
@ -8664,12 +8670,21 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
return fold_builtin_copysign (fndecl, arglist, type);
CASE_FLT_FN (BUILT_IN_FINITE):
case BUILT_IN_FINITED32:
case BUILT_IN_FINITED64:
case BUILT_IN_FINITED128:
return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
CASE_FLT_FN (BUILT_IN_ISINF):
case BUILT_IN_ISINFD32:
case BUILT_IN_ISINFD64:
case BUILT_IN_ISINFD128:
return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
CASE_FLT_FN (BUILT_IN_ISNAN):
case BUILT_IN_ISNAND32:
case BUILT_IN_ISNAND64:
case BUILT_IN_ISNAND128:
return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
case BUILT_IN_ISGREATER:

View File

@ -261,6 +261,9 @@ DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MA
DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@ -321,6 +324,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LON
DEF_GCC_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_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)
@ -619,12 +625,21 @@ DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_tabl
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)

View File

@ -131,6 +131,10 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
tree complex_double_type_node;
tree complex_long_double_type_node;
tree dfloat32_type_node;
tree dfloat64_type_node;
tree_dfloat128_type_node;
tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
@ -1686,6 +1690,13 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
return build_vector_type_for_mode (inner_type, mode);
}
if (mode == TYPE_MODE (dfloat32_type_node))
return dfloat32_type_node;
if (mode == TYPE_MODE (dfloat64_type_node))
return dfloat64_type_node;
if (mode == TYPE_MODE (dfloat128_type_node))
return dfloat128_type_node;
for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
if (TYPE_MODE (TREE_VALUE (t)) == mode)
return TREE_VALUE (t);
@ -2168,6 +2179,14 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
in the type of the operand that is not constant.
TYPE is already properly set. */
}
/* If either arg is decimal float and the other is float, find the
proper common type to use for comparison. */
else if (real1 && real2
&& (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0)))
|| DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1)))))
type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
else if (real1 && real2
&& (TYPE_PRECISION (TREE_TYPE (primop0))
== TYPE_PRECISION (TREE_TYPE (primop1))))
@ -3084,6 +3103,17 @@ c_common_nodes_and_builtins (void)
record_builtin_type (RID_DOUBLE, NULL, double_type_node);
record_builtin_type (RID_MAX, "long double", long_double_type_node);
/* Only supported decimal floating point extension if the target
actually supports underlying modes. */
if (targetm.scalar_mode_supported_p (SDmode)
&& targetm.scalar_mode_supported_p (DDmode)
&& targetm.scalar_mode_supported_p (TDmode))
{
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);
}
lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
get_identifier ("complex int"),
complex_integer_type_node));
@ -4506,6 +4536,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
case MODE_INT:
case MODE_PARTIAL_INT:
case MODE_FLOAT:
case MODE_DECIMAL_FLOAT:
valid_mode = targetm.scalar_mode_supported_p (mode);
break;

View File

@ -72,6 +72,7 @@ enum rid
RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG,
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
RID_TYPES_COMPATIBLE_P,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
/* Too many ways of getting the name of a function as a string */
RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,

View File

@ -96,6 +96,7 @@ builtin_define_float_constants (const char *name_prefix,
int decimal_dig;
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
gcc_assert (fmt->b != 10);
/* The radix of the exponent representation. */
if (type == float_type_node)
@ -266,6 +267,70 @@ builtin_define_float_constants (const char *name_prefix,
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
}
/* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
static void
builtin_define_decimal_float_constants (const char *name_prefix,
const char *suffix,
tree type)
{
const struct real_format *fmt;
char name[64], buf[128], *p;
int digits;
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
/* The number of radix digits, p, in the significand. */
sprintf (name, "__%s_MANT_DIG__", name_prefix);
builtin_define_with_int_value (name, fmt->p);
/* The minimum negative int x such that b**(x-1) is a normalized float. */
sprintf (name, "__%s_MIN_EXP__", name_prefix);
sprintf (buf, "(%d)", fmt->emin);
builtin_define_with_value (name, buf, 0);
/* The maximum int x such that b**(x-1) is a representable float. */
sprintf (name, "__%s_MAX_EXP__", name_prefix);
builtin_define_with_int_value (name, fmt->emax);
/* Compute the minimum representable value. */
sprintf (name, "__%s_MIN__", name_prefix);
sprintf (buf, "1E%d%s", fmt->emin, suffix);
builtin_define_with_value (name, buf, 0);
/* Compute the maximum representable value. */
sprintf (name, "__%s_MAX__", name_prefix);
p = buf;
for (digits = fmt->p; digits; digits--)
{
*p++ = '9';
if (digits == fmt->p)
*p++ = '.';
}
*p = 0;
/* fmt->p plus 1, to account for the decimal point. */
sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax, suffix);
builtin_define_with_value (name, buf, 0);
/* Compute epsilon (the difference between 1 and least value greater
than 1 representable). */
sprintf (name, "__%s_EPSILON__", name_prefix);
sprintf (buf, "1E-%d%s", fmt->p - 1, suffix);
builtin_define_with_value (name, buf, 0);
/* Minimum denormalized postive decimal value. */
sprintf (name, "__%s_DEN__", name_prefix);
p = buf;
for (digits = fmt->p; digits > 1; digits--)
{
*p++ = '0';
if (digits == fmt->p)
*p++ = '.';
}
*p = 0;
sprintf (&buf[fmt->p], "1E%d%s", fmt->emin, suffix);
builtin_define_with_value (name, buf, 0);
}
/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
static void
define__GNUC__ (void)
@ -392,6 +457,10 @@ c_cpp_builtins (cpp_reader *pfile)
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
TARGET_FLT_EVAL_METHOD);
/* And decfloat.h needs this. */
builtin_define_with_int_value ("__DEC_EVAL_METHOD__",
TARGET_DEC_EVAL_METHOD);
builtin_define_float_constants ("FLT", "F", "%s", float_type_node);
/* Cast the double precision constants when single precision constants are
specified. The correct result is computed by the compiler when using
@ -403,6 +472,11 @@ c_cpp_builtins (cpp_reader *pfile)
builtin_define_float_constants ("DBL", "", "%s", double_type_node);
builtin_define_float_constants ("LDBL", "L", "%s", 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 use in assembly language. */
builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);

View File

@ -7069,6 +7069,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else if (specs->typespec_word == cts_float)
error ("both %<long%> and %<float%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat32)
error ("both %<long%> and %<_Decimal32%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat64)
error ("both %<long%> and %<_Decimal64%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat128)
error ("both %<long%> and %<_Decimal128%> in "
"declaration specifiers");
else
specs->long_p = true;
break;
@ -7092,6 +7101,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else if (specs->typespec_word == cts_double)
error ("both %<short%> and %<double%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat32)
error ("both %<short%> and %<_Decimal32%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat64)
error ("both %<short%> and %<_Decimal64%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat128)
error ("both %<short%> and %<_Decimal128%> in "
"declaration specifiers");
else
specs->short_p = true;
break;
@ -7112,6 +7130,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else if (specs->typespec_word == cts_double)
error ("both %<signed%> and %<double%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat32)
error ("both %<signed%> and %<_Decimal32%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat64)
error ("both %<signed%> and %<_Decimal64%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat128)
error ("both %<signed%> and %<_Decimal128%> in "
"declaration specifiers");
else
specs->signed_p = true;
break;
@ -7132,6 +7159,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else if (specs->typespec_word == cts_double)
error ("both %<unsigned%> and %<double%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat32)
error ("both %<unsigned%> and %<_Decimal32%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat64)
error ("both %<unsigned%> and %<_Decimal64%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat128)
error ("both %<unsigned%> and %<_Decimal128%> in "
"declaration specifiers");
else
specs->unsigned_p = true;
break;
@ -7145,6 +7181,15 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else if (specs->typespec_word == cts_bool)
error ("both %<complex%> and %<_Bool%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat32)
error ("both %<complex%> and %<_Decimal32%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat64)
error ("both %<complex%> and %<_Decimal64%> in "
"declaration specifiers");
else if (specs->typespec_word == cts_dfloat128)
error ("both %<complex%> and %<_Decimal128%> in "
"declaration specifiers");
else
specs->complex_p = true;
break;
@ -7250,6 +7295,47 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else
specs->typespec_word = cts_double;
return specs;
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
{
const char *str;
if (i == RID_DFLOAT32)
str = "_Decimal32";
else if (i == RID_DFLOAT64)
str = "_Decimal64";
else
str = "_Decimal128";
if (specs->long_long_p)
error ("both %<long long%> and %<%s%> in "
"declaration specifiers", str);
if (specs->long_p)
error ("both %<long%> and %<%s%> in "
"declaration specifiers", str);
else if (specs->short_p)
error ("both %<short%> and %<%s%> in "
"declaration specifiers", str);
else if (specs->signed_p)
error ("both %<signed%> and %<%s%> in "
"declaration specifiers", str);
else if (specs->unsigned_p)
error ("both %<unsigned%> and %<%s%> in "
"declaration specifiers", str);
else if (specs->complex_p)
error ("both %<complex%> and %<%s%> in "
"declaration specifiers", str);
else if (i == RID_DFLOAT32)
specs->typespec_word = cts_dfloat32;
else if (i == RID_DFLOAT64)
specs->typespec_word = cts_dfloat64;
else
specs->typespec_word = cts_dfloat128;
}
if (!targetm.decimal_float_supported_p ())
error ("decimal floating point not supported for this target");
if (pedantic)
pedwarn ("ISO C does not support decimal floating point");
return specs;
default:
/* ObjC reserved word "id", handled below. */
break;
@ -7527,6 +7613,18 @@ finish_declspecs (struct c_declspecs *specs)
: double_type_node);
}
break;
case cts_dfloat32:
case cts_dfloat64:
case cts_dfloat128:
gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
&& !specs->signed_p && !specs->unsigned_p && !specs->complex_p);
if (specs->typespec_word == cts_dfloat32)
specs->type = dfloat32_type_node;
else if (specs->typespec_word == cts_dfloat64)
specs->type = dfloat64_type_node;
else
specs->type = dfloat128_type_node;
break;
default:
gcc_unreachable ();
}

View File

@ -291,6 +291,8 @@ static const format_length_info printf_length_specs[] =
{ "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
{ "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
{ "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
{ "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 },
{ "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
{ NULL, 0, 0, NULL, 0, 0 }
};
@ -325,6 +327,8 @@ static const format_length_info scanf_length_specs[] =
{ "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
{ "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
{ "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
{ "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 },
{ "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
{ NULL, 0, 0, NULL, 0, 0 }
};
@ -489,34 +493,34 @@ static const format_flag_pair strfmon_flag_pairs[] =
static const format_char_info print_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i", NULL },
{ "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i", NULL },
{ "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i", NULL },
{ "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL },
{ "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#I", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL },
{ "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "-wp0 +'I", "i", NULL },
{ "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
{ "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0'I", "i", NULL },
{ "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL },
{ "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
/* C99 conversion specifiers. */
{ "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL },
{ "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
{ "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL },
{ "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
/* X/Open conversion specifiers. */
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
/* GNU conversion specifiers. */
{ "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
{ "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
};
static const format_char_info asm_fprintf_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
{ "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
{ "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
/* asm_fprintf conversion specifiers. */
{ "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
@ -524,7 +528,7 @@ static const format_char_info asm_fprintf_char_table[] =
{ "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
{ "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
{ "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
};
@ -532,20 +536,20 @@ static const format_char_info asm_fprintf_char_table[] =
static const format_char_info gcc_diag_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
/* Custom conversion specifiers. */
/* %H will require "location_t" at runtime. */
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
/* These will require a "tree" at runtime. */
{ "J", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "J", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
@ -578,20 +582,20 @@ static const format_char_info gcc_tdiag_char_table[] =
static const format_char_info gcc_cdiag_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
/* Custom conversion specifiers. */
/* %H will require "location_t" at runtime. */
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
/* These will require a "tree" at runtime. */
{ "DEFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "DEFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
@ -601,23 +605,23 @@ static const format_char_info gcc_cdiag_char_table[] =
static const format_char_info gcc_cxxdiag_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
/* Custom conversion specifiers. */
/* %H will require "location_t" at runtime. */
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
/* These will require a "tree" at runtime. */
{ "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
{ "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
/* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
@ -644,20 +648,21 @@ static const format_char_info gcc_gfc_char_table[] =
static const format_char_info scan_char_table[] =
{
/* C89 conversion specifiers. */
{ "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w'I", "W", NULL },
{ "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w'I", "W", NULL },
{ "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W", NULL },
{ "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
{ "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
{ "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
{ "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL },
{ "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL },
{ "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL },
{ "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
{ "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
{ "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
{ "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
/* C99 conversion specifiers. */
{ "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
{ "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
{ "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
/* X/Open conversion specifiers. */
{ "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
{ "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
};
@ -690,7 +695,7 @@ static const format_char_info time_char_table[] =
static const format_char_info monetary_char_table[] =
{
{ "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
{ "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
};

View File

@ -35,6 +35,9 @@ enum format_lengths
FMT_LEN_z,
FMT_LEN_t,
FMT_LEN_j,
FMT_LEN_H,
FMT_LEN_D,
FMT_LEN_DD,
FMT_LEN_MAX
};
@ -295,5 +298,11 @@ typedef struct
#define T99_IM { STD_C99, "intmax_t", T_IM }
#define T_UIM &uintmax_type_node
#define T99_UIM { STD_C99, "uintmax_t", T_UIM }
#define T_D32 &dfloat32_type_node
#define TEX_D32 { STD_EXT, "_Decimal32", T_D32 }
#define T_D64 &dfloat64_type_node
#define TEX_D64 { STD_EXT, "_Decimal64", T_D64 }
#define T_D128 &dfloat128_type_node
#define TEX_D128 { STD_EXT, "_Decimal128", T_D128 }
#endif /* GCC_C_FORMAT_H */

View File

@ -640,43 +640,45 @@ interpret_float (const cpp_token *token, unsigned int flags)
REAL_VALUE_TYPE real;
char *copy;
size_t copylen;
const char *type_name;
/* FIXME: make %T work in error/warning, then we don't need type_name. */
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
{
type = long_double_type_node;
type_name = "long double";
}
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
|| flag_single_precision_constant)
{
type = float_type_node;
type_name = "float";
}
/* Decode type based on width and properties. */
if (flags & CPP_N_DFLOAT)
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
type = dfloat128_type_node;
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
type = dfloat32_type_node;
else
type = dfloat64_type_node;
else
{
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
type = long_double_type_node;
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
|| flag_single_precision_constant)
type = float_type_node;
else
type = double_type_node;
type_name = "double";
}
/* Copy the constant to a nul-terminated buffer. If the constant
has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
can't handle them. */
copylen = token->val.str.len;
if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
/* Must be an F or L suffix. */
copylen--;
if (flags & CPP_N_IMAGINARY)
/* I or J suffix. */
copylen--;
if (flags & CPP_N_DFLOAT)
copylen -= 2;
else
{
if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
/* Must be an F or L suffix. */
copylen--;
if (flags & CPP_N_IMAGINARY)
/* I or J suffix. */
copylen--;
}
copy = (char *) alloca (copylen + 1);
memcpy (copy, token->val.str.text, copylen);
copy[copylen] = '\0';
real_from_string (&real, copy);
real_convert (&real, TYPE_MODE (type), &real);
real_from_string3 (&real, copy, TYPE_MODE (type));
/* Both C and C++ require a diagnostic for a floating constant
outside the range of representable values of its type. Since we
@ -684,7 +686,7 @@ interpret_float (const cpp_token *token, unsigned int flags)
appropriate for this to be a mandatory pedwarn rather than
conditioned on -pedantic. */
if (REAL_VALUE_ISINF (real) && pedantic)
pedwarn ("floating constant exceeds range of %<%s%>", type_name);
pedwarn ("floating constant exceeds range of %qT", type);
/* Create a node with determined type and value. */
value = build_real (type, real);

View File

@ -93,6 +93,9 @@ static const struct resword reswords[] =
{
{ "_Bool", RID_BOOL, 0 },
{ "_Complex", RID_COMPLEX, 0 },
{ "_Decimal32", RID_DFLOAT32, D_EXT },
{ "_Decimal64", RID_DFLOAT64, D_EXT },
{ "_Decimal128", RID_DFLOAT128, D_EXT },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
@ -461,6 +464,9 @@ c_token_starts_typename (c_token *token)
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
case RID_BOOL:
case RID_ENUM:
case RID_STRUCT:
@ -532,6 +538,9 @@ c_token_starts_declspecs (c_token *token)
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
case RID_BOOL:
case RID_ENUM:
case RID_STRUCT:
@ -1396,6 +1405,9 @@ c_parser_asm_definition (c_parser *parser)
type-specifier:
typeof-specifier
_Decimal32
_Decimal64
_Decimal128
Objective-C:
@ -1494,6 +1506,9 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
case RID_BOOL:
if (!typespec_ok)
goto out;
@ -2714,6 +2729,9 @@ c_parser_attributes (c_parser *parser)
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_DFLOAT32:
case RID_DFLOAT64:
case RID_DFLOAT128:
case RID_BOOL:
ok = true;
break;

View File

@ -911,6 +911,12 @@ pp_c_floating_constant (c_pretty_printer *pp, tree r)
pp_character (pp, 'f');
else if (TREE_TYPE (r) == long_double_type_node)
pp_character (pp, 'l');
else if (TREE_TYPE (r) == dfloat128_type_node)
pp_string (pp, "dl");
else if (TREE_TYPE (r) == dfloat64_type_node)
pp_string (pp, "dd");
else if (TREE_TYPE (r) == dfloat32_type_node)
pp_string (pp, "df");
}
/* Pretty-print a compound literal expression. GNU extensions include

View File

@ -207,7 +207,10 @@ enum c_typespec_keyword {
cts_char,
cts_int,
cts_float,
cts_double
cts_double,
cts_dfloat32,
cts_dfloat64,
cts_dfloat128
};
/* A sequence of declaration specifiers in C. */

View File

@ -617,6 +617,22 @@ c_common_type (tree t1, tree t2)
if (code2 == REAL_TYPE && code1 != REAL_TYPE)
return t2;
/* If both are real and either are decimal floating point types, use
the decimal floating point type with the greater precision. */
if (code1 == REAL_TYPE && code2 == REAL_TYPE)
{
if (TYPE_MAIN_VARIANT (t1) == dfloat128_type_node
|| TYPE_MAIN_VARIANT (t2) == dfloat128_type_node)
return dfloat128_type_node;
else if (TYPE_MAIN_VARIANT (t1) == dfloat64_type_node
|| TYPE_MAIN_VARIANT (t2) == dfloat64_type_node)
return dfloat64_type_node;
else if (TYPE_MAIN_VARIANT (t1) == dfloat32_type_node
|| TYPE_MAIN_VARIANT (t2) == dfloat32_type_node)
return dfloat32_type_node;
}
/* Both real or both integers; use the one with greater precision. */
if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
@ -2370,10 +2386,37 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
{
/* Warn if any argument is passed as `float',
since without a prototype it would be `double'. */
if (formal_prec == TYPE_PRECISION (float_type_node))
if (formal_prec == TYPE_PRECISION (float_type_node)
&& type != dfloat32_type_node)
warning (0, "passing argument %d of %qE as %<float%> "
"rather than %<double%> due to prototype",
argnum, rname);
/* Warn if mismatch between argument and prototype
for decimal float types. Warn of conversions with
binary float types and of precision narrowing due to
prototype. */
else if (type != TREE_TYPE (val)
&& (type == dfloat32_type_node
|| type == dfloat64_type_node
|| type == dfloat128_type_node
|| TREE_TYPE (val) == dfloat32_type_node
|| TREE_TYPE (val) == dfloat64_type_node
|| TREE_TYPE (val) == dfloat128_type_node)
&& (formal_prec
<= TYPE_PRECISION (TREE_TYPE (val))
|| (type == dfloat128_type_node
&& (TREE_TYPE (val)
!= dfloat64_type_node
&& (TREE_TYPE (val)
!= dfloat32_type_node)))
|| (type == dfloat64_type_node
&& (TREE_TYPE (val)
!= dfloat32_type_node))))
warning (0, "passing argument %d of %qE as %qT "
"rather than %qT due to prototype",
argnum, rname, type, TREE_TYPE (val));
}
/* Detect integer changing in width or signedness.
These warnings are only activated with
@ -2436,7 +2479,8 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
}
else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (val))
< TYPE_PRECISION (double_type_node)))
< TYPE_PRECISION (double_type_node))
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
/* Convert `float' to `double'. */
result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
else if ((invalid_func_diag =

View File

@ -431,6 +431,18 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
#endif
#ifndef DECIMAL32_TYPE_SIZE
#define DECIMAL32_TYPE_SIZE 32
#endif
#ifndef DECIMAL64_TYPE_SIZE
#define DECIMAL64_TYPE_SIZE 64
#endif
#ifndef DECIMAL128_TYPE_SIZE
#define DECIMAL128_TYPE_SIZE 128
#endif
/* Width in bits of a pointer. Mind the value of the macro `Pmode'. */
#ifndef POINTER_SIZE
#define POINTER_SIZE BITS_PER_WORD
@ -696,6 +708,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define TARGET_FLT_EVAL_METHOD 0
#endif
#ifndef TARGET_DEC_EVAL_METHOD
#define TARGET_DEC_EVAL_METHOD 2
#endif
#ifndef HOT_TEXT_SECTION_NAME
#define HOT_TEXT_SECTION_NAME ".text.hot"
#endif

View File

@ -1,5 +1,6 @@
@c Copyright (C) 1988,1989,1992,1993,1994,1996,1998,1999,2000,2001,2002,2003,2004,2005
@c Free Software Foundation, Inc.
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
@c 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@ -32,6 +33,7 @@ extensions, accepted by GCC in C89 mode and in C++.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
* Long Long:: Double-word integers---@code{long long int}.
* Complex:: Data types for complex numbers.
* Decimal Float:: Decimal Floating Point.
* Hex Floats:: Hexadecimal floating-point constants.
* Zero Length:: Zero-length arrays.
* Variable Length:: Arrays whose length is computed at run time.
@ -813,6 +815,42 @@ If the variable's actual name is @code{foo}, the two fictitious
variables are named @code{foo$real} and @code{foo$imag}. You can
examine and set these two fictitious variables with your debugger.
@node Decimal Float
@section Decimal Floating Point
@cindex decimal floating point
@cindex @code{_Decimal32} data type
@cindex @code{_Decimal64} data type
@cindex @code{_Decimal128} data type
@cindex @code{df} integer suffix
@cindex @code{dd} integer suffix
@cindex @code{dl} integer suffix
@cindex @code{DF} integer suffix
@cindex @code{DD} integer suffix
@cindex @code{DL} integer suffix
GNU C supports decimal floating point types in addition to the
standard floating-point types. This extension supports decimal
floating-point arithmetic as defined in IEEE-754R, the proposed
revision of IEEE-754. The C language extension is defined in ISO/IEC
DTR 24732, Draft 5. Support for this functionality will change when
it is accepted into the C standard and might change for new drafts
of the proposal. Calling conventions for any target might also change.
Not all targets support decimal floating point.
Support for decimal floating point includes the arithmetic operators
add, subtract, multiply, divide; unary arithmetic operators;
relational operators; equality operators; and conversions to and from
integer and other floating-point types. Use a suffix @samp{df} or
@samp{DF} in a literal constant of type @code{_Decimal32}, @samp{dd}
or @samp{DD} for @code{_Decimal64}, and @samp{dl} or @samp{DL} for
@code{_Decimal128}.
Passing a decimal floating-point value as an argument to a function
without a prototype is undefined.
Types @code{_Decimal32}, @code{_Decimal64}, and @code{_Decimal128}
are supported by the DWARF2 debug information format.
@node Hex Floats
@section Hex Floats
@cindex hex floats
@ -5661,6 +5699,18 @@ Similar to @code{__builtin_huge_val}, except a warning is generated
if the target floating-point format does not support infinities.
@end deftypefn
@deftypefn {Built-in Function} _Decimal32 __builtin_infd32 (void)
Similar to @code{__builtin_inf}, except the return type is @code{_Decimal32}.
@end deftypefn
@deftypefn {Built-in Function} _Decimal64 __builtin_infd64 (void)
Similar to @code{__builtin_inf}, except the return type is @code{_Decimal64}.
@end deftypefn
@deftypefn {Built-in Function} _Decimal128 __builtin_infd128 (void)
Similar to @code{__builtin_inf}, except the return type is @code{_Decimal128}.
@end deftypefn
@deftypefn {Built-in Function} float __builtin_inff (void)
Similar to @code{__builtin_inf}, except the return type is @code{float}.
This function is suitable for implementing the ISO C99 macro @code{INFINITY}.
@ -5687,6 +5737,18 @@ This function, if given a string literal, is evaluated early enough
that it is considered a compile-time constant.
@end deftypefn
@deftypefn {Built-in Function} _Decimal32 __builtin_nand32 (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{_Decimal32}.
@end deftypefn
@deftypefn {Built-in Function} _Decimal64 __builtin_nand64 (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{_Decimal64}.
@end deftypefn
@deftypefn {Built-in Function} _Decimal128 __builtin_nand128 (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{_Decimal128}.
@end deftypefn
@deftypefn {Built-in Function} float __builtin_nanf (const char *str)
Similar to @code{__builtin_nan}, except the return type is @code{float}.
@end deftypefn

View File

@ -1421,6 +1421,11 @@ precedence for that field, but the alignment of the rest of the structure
may affect its placement.
@end deftypefn
@deftypefn {Target Hook} {bool} TARGET_DECIMAL_FLOAT_SUPPORTED_P (void)
Returns true if the target supports decimal floating point.
The default version of this hook always returns false.
@end deftypefn
@deftypefn {Target Hook} {const char *} TARGET_MANGLE_FUNDAMENTAL_TYPE (tree @var{type})
If your target defines any fundamental types, define this hook to
return the appropriate encoding for these types as part of a C++

108
gcc/ginclude/decfloat.h Normal file
View File

@ -0,0 +1,108 @@
/* Copyright (C) 2005 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 2, 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 COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
the resulting executable to be covered by the GNU General Public
License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General
Public License. */
/*
* Draft C Extension to support decimal floating-pointing arithmetic:
* Characteristics of decimal floating types <decfloat.h>
*/
#ifndef _DECFLOAT_H___
#define _DECFLOAT_H___
/* Number of base-FLT_RADIX digits in the significand, p. */
#undef DEC32_MANT_DIG
#undef DEC64_MANT_DIG
#undef DEC128_MANT_DIG
#define DEC32_MANT_DIG __DEC32_MANT_DIG__
#define DEC64_MANT_DIG __DEC64_MANT_DIG__
#define DEC128_MANT_DIG __DEC128_MANT_DIG__
/* Minimum exponent. */
#undef DEC32_MIN_EXP
#undef DEC64_MIN_EXP
#undef DEC128_MIN_EXP
#define DEC32_MIN_EXP __DEC32_MIN_EXP__
#define DEC64_MIN_EXP __DEC64_MIN_EXP__
#define DEC128_MIN_EXP __DEC128_MIN_EXP__
/* Maximum exponent. */
#undef DEC32_MAX_EXP
#undef DEC64_MAX_EXP
#undef DEC128_MAX_EXP
#define DEC32_MAX_EXP __DEC32_MAX_EXP__
#define DEC64_MAX_EXP __DEC64_MAX_EXP__
#define DEC128_MAX_EXP __DEC128_MAX_EXP__
/* Maximum representable finite decimal floating-point number
(there are 6, 15, and 33 9s after the decimal points respectively). */
#undef DEC32_MAX
#undef DEC64_MAX
#undef DEC128_MAX
#define DEC32_MAX __DEC32_MAX__
#define DEC64_MAX __DEC64_MAX__
#define DEC128_MAX __DEC128_MAX__
/* The difference between 1 and the least value greater than 1 that is
representable in the given floating point type. */
#undef DEC32_EPSILON
#undef DEC64_EPSILON
#undef DEC128_EPSILON
#define DEC32_EPSILON __DEC32_EPSILON__
#define DEC64_EPSILON __DEC64_EPSILON__
#define DEC128_EPSILON __DEC128_EPSILON__
/* Minimum normalized positive floating-point number. */
#undef DEC32_MIN
#undef DEC64_MIN
#undef DEC128_MIN
#define DEC32_MIN __DEC32_MIN__
#define DEC64_MIN __DEC64_MIN__
#define DEC128_MIN __DEC128_MIN__
/* Minimum denormalized positive floating-point number. */
#undef DEC32_DEN
#undef DEC64_DEN
#undef DEC128_DEN
#define DEC32_DEN __DEC32_MIN__
#define DEC64_DEN __DEC64_MIN__
#define DEC128_DEN __DEC128_MIN__
/* The floating-point expression evaluation method.
-1 indeterminate
0 evaluate all operations and constants just to the range and
precision of the type
1 evaluate operations and constants of type _Decimal32
and _Decimal64 to the range and precision of the _Decimal64
type, evaluate _Decimal128 operations and constants to the
range and precision of the _Decimal128 type;
2 evaluate all operations and constants to the range and
precision of the _Decimal128 type.
*/
#undef DECFLT_EVAL_METHOD
#define DECFLT_EVAL_METHOD __DECFLT_EVAL_METHOD__
#endif /* _DECFLOAT_H___ */

View File

@ -366,6 +366,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
#define TARGET_ALLOCATE_INITIAL_VALUE NULL
#ifndef TARGET_DECIMAL_FLOAT_SUPPORTED_P
#define TARGET_DECIMAL_FLOAT_SUPPORTED_P hook_bool_void_false
#endif
#ifndef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS hook_void_void
#endif
@ -557,6 +561,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_INSERT_ATTRIBUTES, \
TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P, \
TARGET_MS_BITFIELD_LAYOUT_P, \
TARGET_DECIMAL_FLOAT_SUPPORTED_P, \
TARGET_ALIGN_ANON_BITFIELD, \
TARGET_INIT_BUILTINS, \
TARGET_EXPAND_BUILTIN, \

View File

@ -352,6 +352,9 @@ struct gcc_target
Microsoft Visual C++ bitfield layout rules. */
bool (* ms_bitfield_layout_p) (tree record_type);
/* True if the target supports decimal floating point. */
bool (* decimal_float_supported_p) (void);
/* Return true if anonymous bitfields affect structure alignment. */
bool (* align_anon_bitfield) (void);

View File

@ -262,6 +262,9 @@ default_scalar_mode_supported_p (enum machine_mode mode)
return true;
return false;
case MODE_DECIMAL_FLOAT:
return false;
default:
gcc_unreachable ();
}

View File

@ -6259,6 +6259,25 @@ build_common_tree_nodes_2 (int short_double)
long_double_ptr_type_node = build_pointer_type (long_double_type_node);
integer_ptr_type_node = build_pointer_type (integer_type_node);
/* Decimal float types. */
dfloat32_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
layout_type (dfloat32_type_node);
TYPE_MODE (dfloat32_type_node) = SDmode;
dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
dfloat64_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
layout_type (dfloat64_type_node);
TYPE_MODE (dfloat64_type_node) = DDmode;
dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
dfloat128_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
layout_type (dfloat128_type_node);
TYPE_MODE (dfloat128_type_node) = TDmode;
dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
complex_integer_type_node = make_node (COMPLEX_TYPE);
TREE_TYPE (complex_integer_type_node) = integer_type_node;
layout_type (complex_integer_type_node);

View File

@ -2933,6 +2933,13 @@ enum tree_index
TI_BOOLEAN_TYPE,
TI_FILEPTR_TYPE,
TI_DFLOAT32_TYPE,
TI_DFLOAT64_TYPE,
TI_DFLOAT128_TYPE,
TI_DFLOAT32_PTR_TYPE,
TI_DFLOAT64_PTR_TYPE,
TI_DFLOAT128_PTR_TYPE,
TI_VOID_LIST_NODE,
TI_MAIN_IDENTIFIER,
@ -3005,6 +3012,14 @@ extern GTY(()) tree global_trees[TI_MAX];
#define boolean_false_node global_trees[TI_BOOLEAN_FALSE]
#define boolean_true_node global_trees[TI_BOOLEAN_TRUE]
/* The decimal floating point types. */
#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 dfloat32_ptr_type_node global_trees[TI_DFLOAT32_PTR_TYPE]
#define dfloat64_ptr_type_node global_trees[TI_DFLOAT64_PTR_TYPE]
#define dfloat128_ptr_type_node global_trees[TI_DFLOAT128_PTR_TYPE]
/* The node that should be placed at the end of a parameter list to
indicate that the function does not take a variable number of
arguments. The TREE_VALUE will be void_type_node and there will be