aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-08-19 18:43:26 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2016-08-19 18:43:26 +0100
commitc65699efcce48d68ef57ab3ce7fc5420fac5cbf9 (patch)
treefaa648423e355c925c007b2939a27316e2af3d9c /gcc/testsuite/gcc.dg
parent71c54f8ea2d79dad967720b67fbeb720566b8b79 (diff)
downloadgcc-c65699efcce48d68ef57ab3ce7fc5420fac5cbf9.zip
gcc-c65699efcce48d68ef57ab3ce7fc5420fac5cbf9.tar.gz
gcc-c65699efcce48d68ef57ab3ce7fc5420fac5cbf9.tar.bz2
Implement C _FloatN, _FloatNx types.
ISO/IEC TS 18661-3:2015 defines C bindings to IEEE interchange and extended types, in the form of _FloatN and _FloatNx type names with corresponding fN/FN and fNx/FNx constant suffixes and FLTN_* / FLTNX_* <float.h> macros. This patch implements support for this feature in GCC. The _FloatN types, for N = 16, 32, 64 or >= 128 and a multiple of 32, are types encoded according to the corresponding IEEE interchange format (endianness unspecified; may use either the NaN conventions recommended in IEEE 754-2008, or the MIPS NaN conventions, since the choice of convention is only an IEEE recommendation, not a requirement). The _FloatNx types, for N = 32, 64 and 128, are IEEE "extended" types: types extending a narrower format with range and precision at least as big as those specified in IEEE 754 for each extended type (and with unspecified representation, but still following IEEE semantics for their values and operations - and with the set of values being determined by the precision and the maximum exponent, which means that while Intel "extended" is suitable for _Float64x, m68k "extended" is not). These types are always distinct from and not compatible with each other and the standard floating types float, double, long double; thus, double, _Float64 and _Float32x may all have the same ABI, but they are three still distinct types. The type names may be used with _Complex to construct corresponding complex types (unlike __float128, which acts more like a typedef name than a keyword - thus, this patch may be considered to fix PR c/32187). The new suffixes can be combined with GNU "i" and "j" suffixes for constants of complex types (e.g. 1.0if128, 2.0f64i). The set of types supported is implementation-defined. In this GCC patch, _Float32 is SFmode if that is suitable; _Float32x and _Float64 are DFmode if that is suitable; _Float128 is TFmode if that is suitable; _Float64x is XFmode if that is suitable, and otherwise TFmode if that is suitable. There is a target hook to override the choices if necessary. "Suitable" means both conforming to the requirements of that type, and supported as a scalar type including in libgcc. The ABI is whatever the back end does for scalars of that mode (but note that _Float32 is passed without promotion in variable arguments, unlike float). All the existing issues with exceptions and rounding modes for existing types apply equally to the new type names. No GCC port supports a floating-point format suitable for _Float128x. Although there is HFmode support for ARM and AArch64, use of that for _Float16 is not enabled. Supporting _Float16 would require additional work on the excess precision aspects of TS 18661-3: there are new values of FLT_EVAL_METHOD, which are not currently supported in GCC, and FLT_EVAL_METHOD == 0 now means that operations and constants on types narrower than float are evaluated to the range and precision of float. Implementing that, so that _Float16 gets evaluated with excess range and precision, would involve changes to the excess precision infrastructure so that the _Float16 case is enabled by default, unlike the x87 case which is only enabled for -fexcess-precision=standard. Other differences between _Float16 and __fp16 would also need to be disentangled. GCC has some prior support for nonstandard floating-point types in the form of __float80 and __float128. Where these were previously types distinct from long double, they are made by this patch into aliases for _Float64x / _Float128 if those types have the required properties. In principle the set of possible _FloatN types is infinite. This patch hardcodes the four such types for N <= 128, but with as much code as possible using loops over types to minimize the number of places with such hardcoding. I don't think it's likely any further such types will be of use in future (or indeed that formats suitable for _Float128x will actually be implemented). There is a corner case that all _FloatN, for N >= 128 and a multiple of 32, should be treated as keywords even when the corresponding type is not supported; I intend to deal with that in a followup patch. Tests are added for various functionality of the new types, mostly using type-generic headers. The tests use dg-add-options to pass any extra options needed to enable the types; this is wired up to use the same options as for __float128 on powerpc to enable _Float128 and _Float64x, and effective-target keywords for runtime support do the same hardware test as for __float128 to make sure the VSX instructions generated by those options are supported. (Corresponding additions would be needed for _Float16 on ARM as well if that were enabled with -mfp16-format=ieee required to use it rather than unconditionally available. Of course, -mfp16-format=alternative enables use of a format which is not compatible with the requirements of the _Float16 type.) C++ note: no support for the new types or constant suffixes is added for C++. C++ decimal floating-point support was very different from the C support, using class types, and the same may well apply to any future C++ bindings for IEEE interchange and extended types. There is a case, however, for supporting at least *f128 constants in C++, so that code using __float128 can use the newer style for constants throughout rather than needing to use the older *q constants in C++. Also, if built-in functions are added that may provide a way in which the types could leak into C++ code. Fortran note: the float128_type_node used in the Fortran front end is renamed to gfc_float128_type_node, since the semantics are different: in particular, if long double has binary128 format, then the new language-independent float128_type_node is a distinct type that also has binary128 format, but the Fortran node is expected to be NULL in that case. Likewise, Fortran's complex_float128_type_node is renamed to gfc_complex_float128_type_node. PowerPC note: the back end had an inconsistency that if TFmode was binary128, *q constants were TFmode instead of KFmode but __float128 was KFmode. This patch follows the same logic as for *q constants, so that _Float128 prefers TFmode (and __float128 becomes an alias for _Float128). ARM note: __fp16 is promoted to double (by convert_arguments) when passed without a prototype / in variable arguments. But this is only about the argument promotion; it is not handled as promoting in c-common.c:self_promoting_args_p / c-typeck.c:c_type_promotes_to, meaning that a K&R function definition for an argument of type __fp16 corresponds to a prototype with an argument of that type, not to one with an argument of type double, whereas a float argument in a K&R function definition corresponds to a double prototype argument - and the same functions are also what's involved in making va_arg give a warning and generate a call to abort when called with type float. This is preserved by this patch, while arranging for _Float16 not to be promoted when passed without a prototype / in variable arguments (the promotion of float being considered a legacy feature, not applied to any new types in C99 or later). TS 18661-3 extends the set of decimal floating-point types similarly, and adds new constant suffixes for the existing types, but this patch does not do anything regarding that extension. This patch does nothing regarding built-in functions, although type-generic functions such as __builtin_isinf work for the new types and associated tests are included. There are at least two levels of built-in function support possible for these types. The minimal level, implemented in <https://gcc.gnu.org/ml/gcc-patches/2016-06/msg01702.html> (which needs updating to use dg-add-options), adds built-in functions similar to those x86 has for __float128: __builtin_inf* __builtin_huge_val*, __builtin_nan*, __builtin_nans*, __builtin_fabs*, __builtin_copysign*. That would be sufficient for glibc to use the *f128 names for built-in functions by default with *q used only for backwards compatibility when using older GCC versions. That would also allow c_cpp_builtins's flag_building_libgcc code, defining __LIBGCC_%s_FUNC_EXT__, to use such suffixes rather than the present code hardcoding logic about target-specific constant suffixes and how those relate to function suffixes. Full built-in function support would cover the full range of built-in functions for existing floating-point types, adding variants for all the new types, except for a few obsolescent functions and non-type-generic variants of type-generic functions. Some but not all references to such functions in GCC use macros such as CASE_FLT_FN to be type-generic; a fair amount of work would be needed to identify all places to update. Adding all those functions would enable optimizations (for constant arguments and otherwise) for TS 18661-3 functions, but it would also substantially expand the enum listing built-in functions (and we've had problems with the size of that enum in the past), and increase the amount of built-in function initialization to do - I don't know what the startup cost involved in built-in function initialization is, but it would be something to consider when adding such a large set of functions. There are also a range of optimizations, in match.pd and elsewhere, that only operate on the three standard floating-point types. Ideally those would be made generic to all floating-point types, but this patch does nothing in that regard. Special care would be needed regarding making sure library functions to which calls are generated actually exist. For example, if sqrt is called on an argument of type _Float32, and the result converted to _Float32, this is equivalent to doing a square root operation directly on _Float32. But if the user's libm does not have the sqrtf32 function, or the name is not reserved because __STDC_WANT_IEC_60559_TYPES_EXT__ was not defined before including <math.h>, you can only do that optimization if you convert to a call to sqrtf instead. DECIMAL_DIG now relates to all supported floating-point formats, not just float, double and long double; I've raised the question with WG14 of how this relates to the formula for DECIMAL_DIG in C11 not considering this. TS 18661-3 says it also covers non-arithmetic formats only supported by library conversion functions; this patch does not add any target hooks to allow for the case where there are such formats wider than any supported for arithmetic types (where e.g. libc supports conversions involving the binary128 representation, but the _Float128 type is not supported). GCC provides its own <tgmath.h> for some targets. No attempt is made to adapt this to handle the new types. Nothing is done regarding debug info for the new types (see the "Debugger support for __float128 type?" thread on gcc@, Sep/Oct 2015). No __SIZEOF_*__ macros are added for the new types. Nothing is done with do_warn_double_promotion. Nothing is done to include the new types in those determining max_align_t, although properly it should be sufficiently aligned for any of those types. The logic for usual arithmetic conversions in c_common_type relies on TYPE_PRECISION for floating-point types, which is less than ideal (doesn't necessarily correspond to whether one type's values are subset of another); looking in more detail at the formats might be better. But since I included code in build_common_tree_nodes to work around rs6000 KFmode having precision 113 not 128, I think it should work. Ideally one might have errors in generic code for the case where the two types do not have one type's values a subset of the other (which is undefined behavior). But the only case where this can actually occur is mixing IBM long double with binary128 on powerpc, and rs6000_invalid_binary_op deals with that at present. TS 18661-3 does not fully specify the type resulting from the usual arithmetic conversions in the case where two _FloatNx types have the same set of values; I arranged the code to prefer the greater value of N in that case. The __FP_FAST_FMA* macros are not extended to cover the new types, since there are no corresponding built-in functions (if built-in fmafN, fmafNx are added, the macros should be extended, and the new macros documented). Also, only a limited set of modes is handled in mode_has_fma. Diagnostics relating to the use of the new types with -pedantic do not try to distinguish them from purely nonstandard types such as __int128 and constant suffixes such as *q. If you use an unsupported _FloatN / _FloatNx type you get a warning about the type defaulting to int after the warning about the type not being supported. That's less than ideal, but it's also a pre-existing condition if you use __int128 on a 32-bit system where it's unsupported. Bootstrapped with no regressions on x86_64-pc-linux-gnu. Other back-end changes minimally tested by building cc1 for ia64-linux-gnu, powerpc64le-linux-gnu, pdp11-none (the last failed for unrelated reasons). PR c/32187 gcc: * tree-core.h (TI_COMPLEX_FLOAT16_TYPE) (TI_COMPLEX_FLOATN_NX_TYPE_FIRST, TI_COMPLEX_FLOAT32_TYPE) (TI_COMPLEX_FLOAT64_TYPE, TI_COMPLEX_FLOAT128_TYPE) (TI_COMPLEX_FLOAT32X_TYPE, TI_COMPLEX_FLOAT64X_TYPE) (TI_COMPLEX_FLOAT128X_TYPE, TI_FLOAT16_TYPE, TI_FLOATN_TYPE_FIRST) (TI_FLOATN_NX_TYPE_FIRST, TI_FLOAT32_TYPE, TI_FLOAT64_TYPE) (TI_FLOAT128_TYPE, TI_FLOATN_TYPE_LAST, TI_FLOAT32X_TYPE) (TI_FLOATNX_TYPE_FIRST, TI_FLOAT64X_TYPE, TI_FLOAT128X_TYPE) (TI_FLOATNX_TYPE_LAST, TI_FLOATN_NX_TYPE_LAST): New enum tree_index values. (NUM_FLOATN_TYPES, NUM_FLOATNX_TYPES, NUM_FLOATN_NX_TYPES): New macros. (struct floatn_type_info): New structure type. (floatn_nx_types): New variable declaration. * tree.h (FLOATN_TYPE_NODE, FLOATN_NX_TYPE_NODE) (FLOATNX_TYPE_NODE, float128_type_node, float64x_type_node) (COMPLEX_FLOATN_NX_TYPE_NODE): New macros. * tree.c (floatn_nx_types): New variable. (build_common_tree_nodes): Initialize _FloatN, _FloatNx and corresponding complex types. * target.def (floatn_mode): New hook. * targhooks.c: Include "real.h". (default_floatn_mode): New function. * targhooks.h (default_floatn_mode): New prototype. * doc/extend.texi (Floating Types): Document _FloatN and _FloatNx types. * doc/sourcebuild.texi (float@var{n}, float@var{n}x): Document new effective-target and dg-add-options keywords. (float@var{n}_runtime, float@var{n}x_runtime, floatn_nx_runtime): Document new effective-target keywords. * doc/tm.texi.in (TARGET_FLOATN_MODE): New @hook. * doc/tm.texi: Regenerate. * ginclude/float.h (LDBL_DECIMAL_DIG): Define to __LDBL_DECIMAL_DIG__, not __DECIMAL_DIG__. [__STDC_WANT_IEC_60559_TYPES_EXT__]: Define macros from TS 18661-3. * real.h (struct real_format): Add field ieee_bits. * real.c (ieee_single_format, mips_single_format) (motorola_single_format, spu_single_format, ieee_double_format) (mips_double_format, motorola_double_format) (ieee_extended_motorola_format, ieee_extended_intel_96_format) (ieee_extended_intel_128_format) (ieee_extended_intel_96_round_53_format, ibm_extended_format) (mips_extended_format, ieee_quad_format, mips_quad_format) (vax_f_format, vax_d_format, vax_g_format, decimal_single_format) (decimal_double_format, decimal_quad_format, ieee_half_format) (arm_half_format, real_internal_format: Initialize ieee_bits field. * config/i386/i386.c (ix86_init_builtin_types): Do not initialize float128_type_node. Set float80_type_node to float64x_type_node if appropriate and long_double_type_node not appropriate. * config/ia64/ia64.c (ia64_init_builtins): Likewise. * config/pdp11/pdp11.c (pdp11_f_format, pdp11_d_format): Initialize ieee_bits field. * config/rs6000/rs6000.c (TARGET_FLOATN_MODE): New macro. (rs6000_init_builtins): Set ieee128_float_type_node to float128_type_node. (rs6000_floatn_mode): New function. gcc/c: * c-tree.h (cts_floatn_nx): New enum c_typespec_keyword value. (struct c_declspecs): Add field floatn_nx_idx. * c-decl.c (declspecs_add_type, finish_declspecs): Handle _FloatN and _FloatNx type specifiers. * c-parser.c (c_keyword_starts_typename, c_token_starts_declspecs) (c_parser_declspecs, c_parser_attribute_any_word) (c_parser_objc_selector): Use CASE_RID_FLOATN_NX. * c-typeck.c (c_common_type): Handle _FloatN and _FloatNx types. (convert_arguments): Avoid promoting _FloatN and _FloatNx types narrower than double. gcc/c-family: * c-common.h (RID_FLOAT16, RID_FLOATN_NX_FIRST, RID_FLOAT32) (RID_FLOAT64, RID_FLOAT128, RID_FLOAT32X, RID_FLOAT64X) (RID_FLOAT128X): New enum rid values. (CASE_RID_FLOATN_NX): New macro. * c-common.c (c_common_reswords): Add _FloatN and _FloatNx keywords. (c_common_type_for_mode): Check for _FloatN and _FloatNx and corresponding complex types. (c_common_nodes_and_builtins): For non-C++, register _FloatN and _FloatNx and corresponding complex types. (keyword_begins_type_specifier): Use CASE_RID_FLOATN_NX. * c-cppbuiltin.c (builtin_define_float_constants): Check _FloatN and _FloatNx types for the widest type for determining DECIMAL_DIG. Define __LDBL_DECIMAL_DIG__ as well as __DECIMAL_DIG__ for long double. Handle FMA_SUFFIX being NULL. (c_cpp_builtins): Call builtin_define_float_constants for _FloatN and _FloatNx types. * c-lex.c (interpret_float): Handle _FloatN and _FloatNx constants. * c-pretty-print.c (pp_c_floating_constant): Handle _FloatN and _FloatNx types. gcc/fortran: * trans-types.h (float128_type_node): Rename to gfc_float128_type_node. (complex_float128_type_node): Rename to gfc_complex_float128_type_node. * iso-c-binding.def, trans-intrinsic.c, trans-types.c: All users changed. gcc/testsuite: * lib/target-supports.exp (check_effective_target_float16) (check_effective_target_float32, check_effective_target_float64) (check_effective_target_float128, check_effective_target_float32x) (check_effective_target_float64x) (check_effective_target_float128x) (check_effective_target_float16_runtime) (check_effective_target_float32_runtime) (check_effective_target_float64_runtime) (check_effective_target_float128_runtime) (check_effective_target_float32x_runtime) (check_effective_target_float64x_runtime) (check_effective_target_float128x_runtime) (check_effective_target_floatn_nx_runtime) (add_options_for_float16, add_options_for_float32) (add_options_for_float64, add_options_for_float128) (add_options_for_float32x, add_options_for_float64x) (add_options_for_float128x): New procedures. * gcc.dg/dfp/floatn.c, gcc.dg/float128-typeof.c, gcc.dg/float128x-typeof.c, gcc.dg/float16-typeof.c, gcc.dg/float32-typeof.c, gcc.dg/float32x-typeof.c, gcc.dg/float64-typeof.c, gcc.dg/float64x-typeof.c, gcc.dg/floatn-arithconv.c, gcc.dg/floatn-errs.c, gcc.dg/floatn-typeof.h, gcc.dg/torture/float128-basic.c, gcc.dg/torture/float128-complex.c, gcc.dg/torture/float128-floath.c, gcc.dg/torture/float128-tg.c, gcc.dg/torture/float128x-basic.c, gcc.dg/torture/float128x-complex.c, gcc.dg/torture/float128x-floath.c, gcc.dg/torture/float128x-tg.c, gcc.dg/torture/float16-basic.c, gcc.dg/torture/float16-complex.c, gcc.dg/torture/float16-floath.c, gcc.dg/torture/float16-tg.c, gcc.dg/torture/float32-basic.c, gcc.dg/torture/float32-complex.c, gcc.dg/torture/float32-floath.c, gcc.dg/torture/float32-tg.c, gcc.dg/torture/float32x-basic.c, gcc.dg/torture/float32x-complex.c, gcc.dg/torture/float32x-floath.c, gcc.dg/torture/float32x-tg.c, gcc.dg/torture/float64-basic.c, gcc.dg/torture/float64-complex.c, gcc.dg/torture/float64-floath.c, gcc.dg/torture/float64-tg.c, gcc.dg/torture/float64x-basic.c, gcc.dg/torture/float64x-complex.c, gcc.dg/torture/float64x-floath.c, gcc.dg/torture/float64x-tg.c, gcc.dg/torture/floatn-basic.h, gcc.dg/torture/floatn-complex.h, gcc.dg/torture/floatn-convert.c, gcc.dg/torture/floatn-floath.h, gcc.dg/torture/floatn-tg.h, gcc.dg/torture/fp-int-convert-float128-ieee-timode.c, gcc.dg/torture/fp-int-convert-float128-ieee.c, gcc.dg/torture/fp-int-convert-float128x-timode.c, gcc.dg/torture/fp-int-convert-float128x.c, gcc.dg/torture/fp-int-convert-float16-timode.c, gcc.dg/torture/fp-int-convert-float16.c, gcc.dg/torture/fp-int-convert-float32-timode.c, gcc.dg/torture/fp-int-convert-float32.c, gcc.dg/torture/fp-int-convert-float32x-timode.c, gcc.dg/torture/fp-int-convert-float32x.c, gcc.dg/torture/fp-int-convert-float64-timode.c, gcc.dg/torture/fp-int-convert-float64.c, gcc.dg/torture/fp-int-convert-float64x-timode.c, gcc.dg/torture/fp-int-convert-float64x.c: New tests. * gcc.dg/torture/fp-int-convert.h (TEST_I_F): Add argument for maximum exponent of floating-point type. Use it in testing whether 0x8...0 fits in the floating-point type. Always treat -1 (signed 0xf...f) as fitting in the floating-point type. (M_OK1): New macro. * gcc.dg/torture/fp-int-convert-double.c, gcc.dg/torture/fp-int-convert-float.c, gcc.dg/torture/fp-int-convert-float128-timode.c, gcc.dg/torture/fp-int-convert-float128.c, gcc.dg/torture/fp-int-convert-float80-timode.c, gcc.dg/torture/fp-int-convert-float80.c, gcc.dg/torture/fp-int-convert-long-double.c, gcc.dg/torture/fp-int-convert-timode.c: Update calls to TEST_I_F. libcpp: * include/cpplib.h (CPP_N_FLOATN, CPP_N_FLOATNX) (CPP_N_WIDTH_FLOATN_NX, CPP_FLOATN_SHIFT, CPP_FLOATN_MAX): New macros. * expr.c (interpret_float_suffix): Handle fN, fNx, FN and FNx suffixes. From-SVN: r239625
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/dfp/floatn.c20
-rw-r--r--gcc/testsuite/gcc.dg/float128-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float128x-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float16-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float32-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float32x-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float64-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/float64x-typeof.c9
-rw-r--r--gcc/testsuite/gcc.dg/floatn-arithconv.c50
-rw-r--r--gcc/testsuite/gcc.dg/floatn-errs.c44
-rw-r--r--gcc/testsuite/gcc.dg/floatn-typeof.h22
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-basic.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-complex.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-floath.c61
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-tg.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-basic.h141
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-complex.h76
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-convert.c104
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-floath.h52
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-tg.h113
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c10
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c10
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c3
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float16-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float16.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float32-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float32.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float64-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float64.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x-timode.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c3
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c10
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c6
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert.h24
67 files changed, 1600 insertions, 41 deletions
diff --git a/gcc/testsuite/gcc.dg/dfp/floatn.c b/gcc/testsuite/gcc.dg/dfp/floatn.c
new file mode 100644
index 0000000..4fa7a09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/floatn.c
@@ -0,0 +1,20 @@
+/* Tests for _FloatN / _FloatNx types: test erroneous mixing with DFP. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target float32x } */
+
+_Decimal32 d32;
+_Float32 f32;
+_Float32x f32x;
+int i;
+
+void
+f (void)
+{
+ (void) (d32 + f32); /* { dg-error "mix operands" } */
+ (void) (f32x * d32); /* { dg-error "mix operands" } */
+ (void) (i ? d32 : f32); /* { dg-error "mix operands" } */
+}
diff --git a/gcc/testsuite/gcc.dg/float128-typeof.c b/gcc/testsuite/gcc.dg/float128-typeof.c
new file mode 100644
index 0000000..b6f95b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float128-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float128 constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128 } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float128x-typeof.c b/gcc/testsuite/gcc.dg/float128x-typeof.c
new file mode 100644
index 0000000..3ab2ce2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float128x-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float128x constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float16-typeof.c b/gcc/testsuite/gcc.dg/float16-typeof.c
new file mode 100644
index 0000000..a781239
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float16-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float16 constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16 } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float32-typeof.c b/gcc/testsuite/gcc.dg/float32-typeof.c
new file mode 100644
index 0000000..4b9ccf8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float32-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float32 constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32 } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float32x-typeof.c b/gcc/testsuite/gcc.dg/float32x-typeof.c
new file mode 100644
index 0000000..9af6077
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float32x-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float32x constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float64-typeof.c b/gcc/testsuite/gcc.dg/float64-typeof.c
new file mode 100644
index 0000000..aa7d504
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float64-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float64 constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64 } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/float64x-typeof.c b/gcc/testsuite/gcc.dg/float64x-typeof.c
new file mode 100644
index 0000000..934d6cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float64x-typeof.c
@@ -0,0 +1,9 @@
+/* Test _Float64x constant types. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-typeof.h"
diff --git a/gcc/testsuite/gcc.dg/floatn-arithconv.c b/gcc/testsuite/gcc.dg/floatn-arithconv.c
new file mode 100644
index 0000000..c3eb24e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/floatn-arithconv.c
@@ -0,0 +1,50 @@
+/* Tests for _FloatN / _FloatNx types: test usual arithmetic
+ conversions. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target float64 } */
+/* { dg-require-effective-target float32x } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+int i;
+
+#define TEST(VAR, TYPE1, TYPE2, RESTYPE) \
+ do \
+ { \
+ typedef __typeof__ ((TYPE1) 0 + (TYPE2) 1) restype; \
+ typedef __typeof__ (i ? (TYPE1) 0 : (TYPE2) 1) restype2; \
+ typedef RESTYPE exptype; \
+ extern restype VAR; \
+ extern restype2 VAR; \
+ extern exptype VAR; \
+ } \
+ while (0)
+
+void
+f (void)
+{
+ TEST (v1, float, double, double);
+#if DBL_MANT_DIG > FLT32_MANT_DIG
+ TEST (v2, double, _Float32, double);
+#endif
+#if DBL_MANT_DIG <= FLT64_MANT_DIG
+ TEST (v3, double, _Float64, _Float64);
+#endif
+#if DBL_MANT_DIG >= FLT32X_MANT_DIG
+ TEST (v4, double, _Float32x, double);
+#endif
+#if FLT_MANT_DIG <= FLT32_MANT_DIG
+ TEST (v5, float, _Float32, _Float32);
+#endif
+#if FLT32X_MANT_DIG <= FLT64_MANT_DIG
+ TEST (v6, _Float32x, _Float64, _Float64);
+#endif
+ TEST (v7, _Float32, _Float64, _Float64);
+ TEST (v8, _Float32, _Float32x, _Float32x);
+}
diff --git a/gcc/testsuite/gcc.dg/floatn-errs.c b/gcc/testsuite/gcc.dg/floatn-errs.c
new file mode 100644
index 0000000..0dcc2f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/floatn-errs.c
@@ -0,0 +1,44 @@
+/* Tests for _FloatN / _FloatNx types: test erroneous code. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target float32x } */
+/* { dg-require-effective-target float64 } */
+
+/* _FloatN, _FloatNx and standard types are incompatible even if they
+ have the same ABI. */
+
+extern float a; /* { dg-message "previous declaration" } */
+extern _Float32 a; /* { dg-error "conflicting" } */
+
+extern double b; /* { dg-message "previous declaration" } */
+extern _Float32x b; /* { dg-error "conflicting" } */
+
+extern _Float64 c; /* { dg-message "previous declaration" } */
+extern _Float32x c; /* { dg-error "conflicting" } */
+
+/* These types are not promoted in old-style function definitions. */
+
+void f (_Float32);
+void
+f (x)
+ _Float32 x;
+{
+}
+
+void g (double); /* { dg-error "prototype declaration" } */
+void
+g (x)
+ _Float32 x; /* { dg-error "match prototype" } */
+{
+}
+
+void h (_Float64); /* { dg-error "prototype declaration" } */
+void
+h (x)
+ _Float32 x; /* { dg-error "match prototype" } */
+{
+}
diff --git a/gcc/testsuite/gcc.dg/floatn-typeof.h b/gcc/testsuite/gcc.dg/floatn-typeof.h
new file mode 100644
index 0000000..4a3e586
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/floatn-typeof.h
@@ -0,0 +1,22 @@
+/* Tests for _FloatN / _FloatNx types: test types of constants.
+ Before including this file, define WIDTH as the value N; define EXT
+ to 1 for _FloatNx and 0 for _FloatN. */
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define CSTU(C) CONCAT4 (C, F, WIDTH, x)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define CSTU(C) CONCAT3 (C, F, WIDTH)
+#endif
+
+extern TYPE test_type;
+extern __typeof (CST (1.0)) test_type;
+extern __typeof (CSTU (1.0)) test_type;
diff --git a/gcc/testsuite/gcc.dg/torture/float128-basic.c b/gcc/testsuite/gcc.dg/torture/float128-basic.c
new file mode 100644
index 0000000..b23d45b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float128. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128-complex.c b/gcc/testsuite/gcc.dg/torture/float128-complex.c
new file mode 100644
index 0000000..fe93fe6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float128 complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128-floath.c b/gcc/testsuite/gcc.dg/torture/float128-floath.c
new file mode 100644
index 0000000..68147c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float128 <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-floath.h"
+
+#ifndef FLT128_MANT_DIG
+# error "FLT128_MANT_DIG undefined"
+#endif
+
+#ifndef FLT128_DECIMAL_DIG
+# error "FLT128_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT128_DIG
+# error "FLT128_DIG undefined"
+#endif
+
+#ifndef FLT128_MIN_EXP
+# error "FLT128_MIN_EXP undefined"
+#endif
+
+#ifndef FLT128_MIN_10_EXP
+# error "FLT128_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT128_MAX_EXP
+# error "FLT128_MAX_EXP undefined"
+#endif
+
+#ifndef FLT128_MAX_10_EXP
+# error "FLT128_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT128_MAX
+# error "FLT128_MAX undefined"
+#endif
+
+#ifndef FLT128_EPSILON
+# error "FLT128_EPSILON undefined"
+#endif
+
+#ifndef FLT128_MIN
+# error "FLT128_MIN undefined"
+#endif
+
+#ifndef FLT128_TRUE_MIN
+# error "FLT128_TRUE_MIN undefined"
+#endif
+
+#if FLT128_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT128_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT128_MANT_DIG != 113 || FLT128_MAX_EXP != 16384 || FLT128_MIN_EXP != -16381
+# error "_Float128 bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float128-tg.c b/gcc/testsuite/gcc.dg/torture/float128-tg.c
new file mode 100644
index 0000000..c1b6398
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float128 type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-basic.c b/gcc/testsuite/gcc.dg/torture/float128x-basic.c
new file mode 100644
index 0000000..75c5a28
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float128x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-complex.c b/gcc/testsuite/gcc.dg/torture/float128x-complex.c
new file mode 100644
index 0000000..185b501
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float128x complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-floath.c b/gcc/testsuite/gcc.dg/torture/float128x-floath.c
new file mode 100644
index 0000000..0fc3db2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float128x <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-floath.h"
+
+#ifndef FLT128X_MANT_DIG
+# error "FLT128X_MANT_DIG undefined"
+#endif
+
+#ifndef FLT128X_DECIMAL_DIG
+# error "FLT128X_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT128X_DIG
+# error "FLT128X_DIG undefined"
+#endif
+
+#ifndef FLT128X_MIN_EXP
+# error "FLT128X_MIN_EXP undefined"
+#endif
+
+#ifndef FLT128X_MIN_10_EXP
+# error "FLT128X_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT128X_MAX_EXP
+# error "FLT128X_MAX_EXP undefined"
+#endif
+
+#ifndef FLT128X_MAX_10_EXP
+# error "FLT128X_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT128X_MAX
+# error "FLT128X_MAX undefined"
+#endif
+
+#ifndef FLT128X_EPSILON
+# error "FLT128X_EPSILON undefined"
+#endif
+
+#ifndef FLT128X_MIN
+# error "FLT128X_MIN undefined"
+#endif
+
+#ifndef FLT128X_TRUE_MIN
+# error "FLT128X_TRUE_MIN undefined"
+#endif
+
+#if FLT128X_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT128X_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT128X_MANT_DIG < 128 || FLT128X_MAX_EXP < 65536 || FLT128X_MIN_EXP + FLT128X_MAX_EXP != 3
+# error "_Float128x bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-tg.c b/gcc/testsuite/gcc.dg/torture/float128x-tg.c
new file mode 100644
index 0000000..0dc1e0f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float128x type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-basic.c b/gcc/testsuite/gcc.dg/torture/float16-basic.c
new file mode 100644
index 0000000..e94aa20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float16. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-complex.c b/gcc/testsuite/gcc.dg/torture/float16-complex.c
new file mode 100644
index 0000000..463e703
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float16 complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-floath.c b/gcc/testsuite/gcc.dg/torture/float16-floath.c
new file mode 100644
index 0000000..6857c2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float16 <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-floath.h"
+
+#ifndef FLT16_MANT_DIG
+# error "FLT16_MANT_DIG undefined"
+#endif
+
+#ifndef FLT16_DECIMAL_DIG
+# error "FLT16_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT16_DIG
+# error "FLT16_DIG undefined"
+#endif
+
+#ifndef FLT16_MIN_EXP
+# error "FLT16_MIN_EXP undefined"
+#endif
+
+#ifndef FLT16_MIN_10_EXP
+# error "FLT16_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT16_MAX_EXP
+# error "FLT16_MAX_EXP undefined"
+#endif
+
+#ifndef FLT16_MAX_10_EXP
+# error "FLT16_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT16_MAX
+# error "FLT16_MAX undefined"
+#endif
+
+#ifndef FLT16_EPSILON
+# error "FLT16_EPSILON undefined"
+#endif
+
+#ifndef FLT16_MIN
+# error "FLT16_MIN undefined"
+#endif
+
+#ifndef FLT16_TRUE_MIN
+# error "FLT16_TRUE_MIN undefined"
+#endif
+
+#if FLT16_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT16_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT16_MANT_DIG != 11 || FLT16_MAX_EXP != 16 || FLT16_MIN_EXP != -13
+# error "_Float16 bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float16-tg.c b/gcc/testsuite/gcc.dg/torture/float16-tg.c
new file mode 100644
index 0000000..39e8285
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float16 type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-basic.c b/gcc/testsuite/gcc.dg/torture/float32-basic.c
new file mode 100644
index 0000000..2d3e7a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float32. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-complex.c b/gcc/testsuite/gcc.dg/torture/float32-complex.c
new file mode 100644
index 0000000..8717a3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float32 complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-floath.c b/gcc/testsuite/gcc.dg/torture/float32-floath.c
new file mode 100644
index 0000000..795cb21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float32 <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-floath.h"
+
+#ifndef FLT32_MANT_DIG
+# error "FLT32_MANT_DIG undefined"
+#endif
+
+#ifndef FLT32_DECIMAL_DIG
+# error "FLT32_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT32_DIG
+# error "FLT32_DIG undefined"
+#endif
+
+#ifndef FLT32_MIN_EXP
+# error "FLT32_MIN_EXP undefined"
+#endif
+
+#ifndef FLT32_MIN_10_EXP
+# error "FLT32_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT32_MAX_EXP
+# error "FLT32_MAX_EXP undefined"
+#endif
+
+#ifndef FLT32_MAX_10_EXP
+# error "FLT32_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT32_MAX
+# error "FLT32_MAX undefined"
+#endif
+
+#ifndef FLT32_EPSILON
+# error "FLT32_EPSILON undefined"
+#endif
+
+#ifndef FLT32_MIN
+# error "FLT32_MIN undefined"
+#endif
+
+#ifndef FLT32_TRUE_MIN
+# error "FLT32_TRUE_MIN undefined"
+#endif
+
+#if FLT32_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT32_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT32_MANT_DIG != 24 || FLT32_MAX_EXP != 128 || FLT32_MIN_EXP != -125
+# error "_Float32 bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float32-tg.c b/gcc/testsuite/gcc.dg/torture/float32-tg.c
new file mode 100644
index 0000000..da480ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float32 type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-basic.c b/gcc/testsuite/gcc.dg/torture/float32x-basic.c
new file mode 100644
index 0000000..f2abc33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float32x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-complex.c b/gcc/testsuite/gcc.dg/torture/float32x-complex.c
new file mode 100644
index 0000000..4a63a50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float32x complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-floath.c b/gcc/testsuite/gcc.dg/torture/float32x-floath.c
new file mode 100644
index 0000000..49e7ba4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float32x <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-floath.h"
+
+#ifndef FLT32X_MANT_DIG
+# error "FLT32X_MANT_DIG undefined"
+#endif
+
+#ifndef FLT32X_DECIMAL_DIG
+# error "FLT32X_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT32X_DIG
+# error "FLT32X_DIG undefined"
+#endif
+
+#ifndef FLT32X_MIN_EXP
+# error "FLT32X_MIN_EXP undefined"
+#endif
+
+#ifndef FLT32X_MIN_10_EXP
+# error "FLT32X_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT32X_MAX_EXP
+# error "FLT32X_MAX_EXP undefined"
+#endif
+
+#ifndef FLT32X_MAX_10_EXP
+# error "FLT32X_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT32X_MAX
+# error "FLT32X_MAX undefined"
+#endif
+
+#ifndef FLT32X_EPSILON
+# error "FLT32X_EPSILON undefined"
+#endif
+
+#ifndef FLT32X_MIN
+# error "FLT32X_MIN undefined"
+#endif
+
+#ifndef FLT32X_TRUE_MIN
+# error "FLT32X_TRUE_MIN undefined"
+#endif
+
+#if FLT32X_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT32X_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT32X_MANT_DIG < 32 || FLT32X_MAX_EXP < 1024 || FLT32X_MIN_EXP + FLT32X_MAX_EXP != 3
+# error "_Float32x bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-tg.c b/gcc/testsuite/gcc.dg/torture/float32x-tg.c
new file mode 100644
index 0000000..9f9a3bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float32x type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-basic.c b/gcc/testsuite/gcc.dg/torture/float64-basic.c
new file mode 100644
index 0000000..decb05f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float64. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-complex.c b/gcc/testsuite/gcc.dg/torture/float64-complex.c
new file mode 100644
index 0000000..6a832c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float64 complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-floath.c b/gcc/testsuite/gcc.dg/torture/float64-floath.c
new file mode 100644
index 0000000..a03d2e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float64 <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-floath.h"
+
+#ifndef FLT64_MANT_DIG
+# error "FLT64_MANT_DIG undefined"
+#endif
+
+#ifndef FLT64_DECIMAL_DIG
+# error "FLT64_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT64_DIG
+# error "FLT64_DIG undefined"
+#endif
+
+#ifndef FLT64_MIN_EXP
+# error "FLT64_MIN_EXP undefined"
+#endif
+
+#ifndef FLT64_MIN_10_EXP
+# error "FLT64_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT64_MAX_EXP
+# error "FLT64_MAX_EXP undefined"
+#endif
+
+#ifndef FLT64_MAX_10_EXP
+# error "FLT64_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT64_MAX
+# error "FLT64_MAX undefined"
+#endif
+
+#ifndef FLT64_EPSILON
+# error "FLT64_EPSILON undefined"
+#endif
+
+#ifndef FLT64_MIN
+# error "FLT64_MIN undefined"
+#endif
+
+#ifndef FLT64_TRUE_MIN
+# error "FLT64_TRUE_MIN undefined"
+#endif
+
+#if FLT64_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT64_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT64_MANT_DIG != 53 || FLT64_MAX_EXP != 1024 || FLT64_MIN_EXP != -1021
+# error "_Float64 bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float64-tg.c b/gcc/testsuite/gcc.dg/torture/float64-tg.c
new file mode 100644
index 0000000..c970d53
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float64 type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-basic.c b/gcc/testsuite/gcc.dg/torture/float64x-basic.c
new file mode 100644
index 0000000..7a140af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-basic.c
@@ -0,0 +1,9 @@
+/* Test _Float64x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-basic.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-complex.c b/gcc/testsuite/gcc.dg/torture/float64x-complex.c
new file mode 100644
index 0000000..cb573be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-complex.c
@@ -0,0 +1,9 @@
+/* Test _Float64x complex arithmetic. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-complex.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-floath.c b/gcc/testsuite/gcc.dg/torture/float64x-floath.c
new file mode 100644
index 0000000..11eddc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-floath.c
@@ -0,0 +1,61 @@
+/* Test _Float64x <float.h> macros. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-floath.h"
+
+#ifndef FLT64X_MANT_DIG
+# error "FLT64X_MANT_DIG undefined"
+#endif
+
+#ifndef FLT64X_DECIMAL_DIG
+# error "FLT64X_DECIMAL_DIG undefined"
+#endif
+
+#ifndef FLT64X_DIG
+# error "FLT64X_DIG undefined"
+#endif
+
+#ifndef FLT64X_MIN_EXP
+# error "FLT64X_MIN_EXP undefined"
+#endif
+
+#ifndef FLT64X_MIN_10_EXP
+# error "FLT64X_MIN_10_EXP undefined"
+#endif
+
+#ifndef FLT64X_MAX_EXP
+# error "FLT64X_MAX_EXP undefined"
+#endif
+
+#ifndef FLT64X_MAX_10_EXP
+# error "FLT64X_MAX_10_EXP undefined"
+#endif
+
+#ifndef FLT64X_MAX
+# error "FLT64X_MAX undefined"
+#endif
+
+#ifndef FLT64X_EPSILON
+# error "FLT64X_EPSILON undefined"
+#endif
+
+#ifndef FLT64X_MIN
+# error "FLT64X_MIN undefined"
+#endif
+
+#ifndef FLT64X_TRUE_MIN
+# error "FLT64X_TRUE_MIN undefined"
+#endif
+
+#if FLT64X_DECIMAL_DIG > DECIMAL_DIG
+# error "FLT64X_DECIMAL_DIG > DECIMAL_DIG"
+#endif
+
+#if FLT64X_MANT_DIG < 64 || FLT64X_MAX_EXP < 16384 || FLT64X_MIN_EXP + FLT64X_MAX_EXP != 3
+# error "_Float64x bad format"
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-tg.c b/gcc/testsuite/gcc.dg/torture/float64x-tg.c
new file mode 100644
index 0000000..ac14675
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-tg.c
@@ -0,0 +1,9 @@
+/* Test _Float64x type-generic built-in functions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-tg.h"
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-basic.h b/gcc/testsuite/gcc.dg/torture/floatn-basic.h
new file mode 100644
index 0000000..9131f46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-basic.h
@@ -0,0 +1,141 @@
+/* Basic tests for _FloatN / _FloatNx types: compile and execution
+ tests for valid code. Before including this file, define WIDTH as
+ the value N; define EXT to 1 for _FloatNx and 0 for _FloatN. */
+
+#include <stdarg.h>
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define CSTU(C) CONCAT4 (C, F, WIDTH, x)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define CSTU(C) CONCAT3 (C, F, WIDTH)
+#endif
+
+extern void exit (int);
+extern void abort (void);
+
+volatile TYPE a = CST (1.0), b = CSTU (2.5), c = -CST (2.5);
+volatile TYPE a2 = CST (1.0), z = CST (0.0), nz = -CST (0.0);
+
+/* These types are not subject to default argument promotions. */
+
+TYPE
+vafn (TYPE arg1, ...)
+{
+ va_list ap;
+ TYPE ret;
+ va_start (ap, arg1);
+ ret = arg1 + va_arg (ap, TYPE);
+ va_end (ap);
+ return ret;
+}
+
+TYPE
+krfn (arg)
+ TYPE arg;
+{
+ return arg + 1;
+}
+
+TYPE krprofn (TYPE);
+TYPE
+krprofn (arg)
+ TYPE arg;
+{
+ return arg * 3;
+}
+
+TYPE
+profn (TYPE arg)
+{
+ return arg / 4;
+}
+
+int
+main (void)
+{
+ volatile TYPE r;
+ r = -b;
+ if (r != c)
+ abort ();
+ r = a + b;
+ if (r != CST (3.5))
+ abort ();
+ r = a - b;
+ if (r != -CST (1.5))
+ abort ();
+ r = 2 * c;
+ if (r != -5)
+ abort ();
+ r = b * c;
+ if (r != -CST (6.25))
+ abort ();
+ r = b / (a + a);
+ if (r != CST (1.25))
+ abort ();
+ r = c * 3;
+ if (r != -CST (7.5))
+ abort ();
+ volatile int i = r;
+ if (i != -7)
+ abort ();
+ r = vafn (a, c);
+ if (r != -CST (1.5))
+ abort ();
+ r = krfn (b);
+ if (r != CST (3.5))
+ abort ();
+ r = krprofn (a);
+ if (r != CST (3.0))
+ abort ();
+ r = profn (a);
+ if (r != CST (0.25))
+ abort ();
+ if ((a < b) != 1)
+ abort ();
+ if ((b < a) != 0)
+ abort ();
+ if ((a < a2) != 0)
+ abort ();
+ if ((nz < z) != 0)
+ abort ();
+ if ((a <= b) != 1)
+ abort ();
+ if ((b <= a) != 0)
+ abort ();
+ if ((a <= a2) != 1)
+ abort ();
+ if ((nz <= z) != 1)
+ abort ();
+ if ((a > b) != 0)
+ abort ();
+ if ((b > a) != 1)
+ abort ();
+ if ((a > a2) != 0)
+ abort ();
+ if ((nz > z) != 0)
+ abort ();
+ if ((a >= b) != 0)
+ abort ();
+ if ((b >= a) != 1)
+ abort ();
+ if ((a >= a2) != 1)
+ abort ();
+ if ((nz >= z) != 1)
+ abort ();
+ i = (nz == z);
+ if (i != 1)
+ abort ();
+ i = (a == b);
+ if (i != 0)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-complex.h b/gcc/testsuite/gcc.dg/torture/floatn-complex.h
new file mode 100644
index 0000000..7e32faf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-complex.h
@@ -0,0 +1,76 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+ valid code with complex arithmetic. Before including this file,
+ define WIDTH as the value N; define EXT to 1 for _FloatNx and 0 for
+ _FloatN. */
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define CSTI(C) CONCAT4 (C, if, WIDTH, x)
+# define CSTI2(C) CONCAT4 (C, F, WIDTH, xi)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define CSTI(C) CONCAT3 (C, if, WIDTH)
+# define CSTI2(C) CONCAT4 (C, F, WIDTH, i)
+#endif
+
+extern void exit (int);
+extern void abort (void);
+
+volatile TYPE a = CST (1.0);
+volatile _Complex TYPE b = CST (2.0) + CSTI (3.0);
+volatile _Complex TYPE c = CST (2.0) + CSTI2 (3.0);
+volatile _Complex TYPE d = __builtin_complex (CST (2.0), CST (3.0));
+
+_Complex TYPE
+fn (_Complex TYPE arg)
+{
+ return arg / 4;
+}
+
+int
+main (void)
+{
+ volatile _Complex TYPE r;
+ if (b != c)
+ abort ();
+ if (b != d)
+ abort ();
+ r = a + b;
+ if (__real__ r != CST (3.0) || __imag__ r != CST (3.0))
+ abort ();
+ r += d;
+ if (__real__ r != CST (5.0) || __imag__ r != CST (6.0))
+ abort ();
+ r -= a;
+ if (__real__ r != CST (4.0) || __imag__ r != CST (6.0))
+ abort ();
+ r /= (a + a);
+ if (__real__ r != CST (2.0) || __imag__ r != CST (3.0))
+ abort ();
+ r *= (a + a);
+ if (__real__ r != CST (4.0) || __imag__ r != CST (6.0))
+ abort ();
+ r -= b;
+ if (__real__ r != CST (2.0) || __imag__ r != CST (3.0))
+ abort ();
+ r *= r;
+ if (__real__ r != -CST (5.0) || __imag__ r != CST (12.0))
+ abort ();
+ /* Division may not be exact, so round result before comparing. */
+ r /= b;
+ r += __builtin_complex (CST (100.0), CST (100.0));
+ r -= __builtin_complex (CST (100.0), CST (100.0));
+ if (r != b)
+ abort ();
+ r = fn (r);
+ if (__real__ r != CST (0.5) || __imag__ r != CST (0.75))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-convert.c b/gcc/testsuite/gcc.dg/torture/floatn-convert.c
new file mode 100644
index 0000000..741ffc8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-convert.c
@@ -0,0 +1,104 @@
+/* Tests for _FloatN / _FloatNx types: test conversions. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float128 } */
+/* { dg-add-options float32x } */
+/* { dg-add-options float64x } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target floatn_nx_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#ifndef FLT16_MAX
+# define _Float16 _Float32
+# define FLT16_MAX FLT32_MAX
+# define FLT16_MANT_DIG FLT32_MANT_DIG
+# define FLT16_EPSILON FLT32_EPSILON
+#endif
+
+#ifndef FLT64_MAX
+# define _Float64 _Float32
+# define FLT64_MAX FLT32_MAX
+# define FLT64_MANT_DIG FLT32_MANT_DIG
+# define FLT64_EPSILON FLT32_EPSILON
+#endif
+
+#ifndef FLT128_MAX
+# define _Float128 _Float32
+# define FLT128_MAX FLT32_MAX
+# define FLT128_MANT_DIG FLT32_MANT_DIG
+# define FLT128_EPSILON FLT32_EPSILON
+#endif
+
+#ifndef FLT32X_MAX
+# define _Float32x _Float32
+# define FLT32X_MAX FLT32_MAX
+# define FLT32X_MANT_DIG FLT32_MANT_DIG
+# define FLT32X_EPSILON FLT32_EPSILON
+#endif
+
+#ifndef FLT64X_MAX
+# define _Float64x _Float32
+# define FLT64X_MAX FLT32_MAX
+# define FLT64X_MANT_DIG FLT32_MANT_DIG
+# define FLT64X_EPSILON FLT32_EPSILON
+#endif
+
+#ifndef FLT128X_MAX
+# define _Float128x _Float32
+# define FLT128X_MAX FLT32_MAX
+# define FLT128X_MANT_DIG FLT32_MANT_DIG
+# define FLT128X_EPSILON FLT32_EPSILON
+#endif
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+
+extern void exit (int);
+extern void abort (void);
+
+#define DO_TEST(TYPE1, PFX1, TYPE2, PFX2) \
+ do \
+ { \
+ volatile TYPE1 a = (TYPE1) 1 + CONCAT (PFX1, _EPSILON); \
+ volatile TYPE2 b = (TYPE2) a; \
+ volatile TYPE2 expected; \
+ if (CONCAT (PFX2, _MANT_DIG) < CONCAT (PFX1, _MANT_DIG)) \
+ expected = (TYPE2) 1; \
+ else \
+ expected = (TYPE2) 1 + (TYPE2) CONCAT (PFX1, _EPSILON); \
+ if (b != expected) \
+ abort (); \
+ } \
+ while (0)
+
+#define DO_TEST1(TYPE1, PFX1) \
+ do \
+ { \
+ DO_TEST (TYPE1, PFX1, _Float16, FLT16); \
+ DO_TEST (TYPE1, PFX1, _Float32, FLT32); \
+ DO_TEST (TYPE1, PFX1, _Float64, FLT64); \
+ DO_TEST (TYPE1, PFX1, _Float128, FLT128); \
+ DO_TEST (TYPE1, PFX1, _Float32x, FLT32X); \
+ DO_TEST (TYPE1, PFX1, _Float64x, FLT64X); \
+ DO_TEST (TYPE1, PFX1, _Float128x, FLT128X); \
+ } \
+ while (0)
+
+int
+main (void)
+{
+ DO_TEST1 (_Float16, FLT16);
+ DO_TEST1 (_Float32, FLT32);
+ DO_TEST1 (_Float64, FLT64);
+ DO_TEST1 (_Float128, FLT128);
+ DO_TEST1 (_Float32x, FLT32X);
+ DO_TEST1 (_Float64x, FLT64X);
+ DO_TEST1 (_Float128x, FLT128X);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-floath.h b/gcc/testsuite/gcc.dg/torture/floatn-floath.h
new file mode 100644
index 0000000..a09b59e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-floath.h
@@ -0,0 +1,52 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+ <float.h>. Before including this file, define WIDTH as the value
+ N; define EXT to 1 for _FloatNx and 0 for _FloatN. */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define FMAC(M) CONCAT4 (FLT, WIDTH, X_, M)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define FMAC(M) CONCAT4 (FLT, WIDTH, _, M)
+#endif
+
+extern void exit (int);
+extern void abort (void);
+
+int
+main (void)
+{
+ volatile TYPE a = CST (1.0);
+ for (int i = 0; i >= FMAC (MIN_EXP); i--)
+ a *= CST (0.5);
+ if (a != FMAC (MIN))
+ abort ();
+ for (int i = 0; i < FMAC (MANT_DIG) - 1; i++)
+ a *= CST (0.5);
+ if (a != FMAC (TRUE_MIN))
+ abort ();
+ a *= CST (0.5);
+ if (a != CST (0.0))
+ abort ();
+ a = FMAC (EPSILON);
+ for (int i = 0; i < FMAC (MANT_DIG) - 1; i++)
+ a *= CST (2.0);
+ if (a != CST (1.0))
+ abort ();
+ a = FMAC (MAX);
+ for (int i = 0; i < FMAC (MAX_EXP); i++)
+ a *= CST (0.5);
+ if (a != CST (1.0) - FMAC (EPSILON) * CST (0.5))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-tg.h b/gcc/testsuite/gcc.dg/torture/floatn-tg.h
new file mode 100644
index 0000000..8222297
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-tg.h
@@ -0,0 +1,113 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+ type-generic built-in functions. Before including this file,
+ define WIDTH as the value N; define EXT to 1 for _FloatNx and 0 for
+ _FloatN. */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define TRUE_MIN CONCAT3 (FLT, WIDTH, X_TRUE_MIN)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define TRUE_MIN CONCAT3 (FLT, WIDTH, _TRUE_MIN)
+#endif
+
+extern void exit (int);
+extern void abort (void);
+
+volatile TYPE inf = __builtin_inf (), nanval = __builtin_nan ("");
+volatile TYPE zero = CST (0.0), negzero = -CST (0.0), one = CST (1.0);
+volatile TYPE true_min = TRUE_MIN;
+
+int
+main (void)
+{
+ if (__builtin_signbit (inf) != 0)
+ abort ();
+ if (__builtin_signbit (zero) != 0)
+ abort ();
+ if (__builtin_signbit (negzero) == 0)
+ abort ();
+ if (__builtin_isfinite (nanval) != 0)
+ abort ();
+ if (__builtin_isfinite (inf) != 0)
+ abort ();
+ if (__builtin_isfinite (one) == 0)
+ abort ();
+ if (__builtin_isinf (nanval) != 0)
+ abort ();
+ if (__builtin_isinf (inf) == 0)
+ abort ();
+ if (__builtin_isnan (nanval) == 0)
+ abort ();
+ if (__builtin_isnan (inf) != 0)
+ abort ();
+ if (__builtin_isnormal (inf) != 0)
+ abort ();
+ if (__builtin_isnormal (one) == 0)
+ abort ();
+ if (__builtin_isnormal (nanval) != 0)
+ abort ();
+ if (__builtin_isnormal (zero) != 0)
+ abort ();
+ if (__builtin_isnormal (true_min) != 0)
+ abort ();
+ if (__builtin_islessequal (zero, one) != 1)
+ abort ();
+ if (__builtin_islessequal (one, zero) != 0)
+ abort ();
+ if (__builtin_islessequal (zero, negzero) != 1)
+ abort ();
+ if (__builtin_islessequal (zero, nanval) != 0)
+ abort ();
+ if (__builtin_isless (zero, one) != 1)
+ abort ();
+ if (__builtin_isless (one, zero) != 0)
+ abort ();
+ if (__builtin_isless (zero, negzero) != 0)
+ abort ();
+ if (__builtin_isless (zero, nanval) != 0)
+ abort ();
+ if (__builtin_isgreaterequal (zero, one) != 0)
+ abort ();
+ if (__builtin_isgreaterequal (one, zero) != 1)
+ abort ();
+ if (__builtin_isgreaterequal (zero, negzero) != 1)
+ abort ();
+ if (__builtin_isgreaterequal (zero, nanval) != 0)
+ abort ();
+ if (__builtin_isgreater (zero, one) != 0)
+ abort ();
+ if (__builtin_isgreater (one, zero) != 1)
+ abort ();
+ if (__builtin_isgreater (zero, negzero) != 0)
+ abort ();
+ if (__builtin_isgreater (zero, nanval) != 0)
+ abort ();
+ if (__builtin_islessgreater (zero, one) != 1)
+ abort ();
+ if (__builtin_islessgreater (one, zero) != 1)
+ abort ();
+ if (__builtin_islessgreater (zero, negzero) != 0)
+ abort ();
+ if (__builtin_islessgreater (zero, nanval) != 0)
+ abort ();
+ if (__builtin_isunordered (zero, one) != 0)
+ abort ();
+ if (__builtin_isunordered (one, zero) != 0)
+ abort ();
+ if (__builtin_isunordered (zero, negzero) != 0)
+ abort ();
+ if (__builtin_isunordered (zero, nanval) != 1)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c
index 39ec3cd..f2446d7 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c
@@ -9,10 +9,10 @@
int
main (void)
{
- TEST_I_F(signed char, unsigned char, double, DBL_MANT_DIG);
- TEST_I_F(signed short, unsigned short, double, DBL_MANT_DIG);
- TEST_I_F(signed int, unsigned int, double, DBL_MANT_DIG);
- TEST_I_F(signed long, unsigned long, double, DBL_MANT_DIG);
- TEST_I_F(signed long long, unsigned long long, double, DBL_MANT_DIG);
+ TEST_I_F(signed char, unsigned char, double, DBL_MANT_DIG, DBL_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, double, DBL_MANT_DIG, DBL_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, double, DBL_MANT_DIG, DBL_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, double, DBL_MANT_DIG, DBL_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, double, DBL_MANT_DIG, DBL_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c
index 7fca1df..f0f371b 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c
@@ -9,10 +9,10 @@
int
main (void)
{
- TEST_I_F(signed char, unsigned char, float, FLT_MANT_DIG);
- TEST_I_F(signed short, unsigned short, float, FLT_MANT_DIG);
- TEST_I_F(signed int, unsigned int, float, FLT_MANT_DIG);
- TEST_I_F(signed long, unsigned long, float, FLT_MANT_DIG);
- TEST_I_F(signed long long, unsigned long long, float, FLT_MANT_DIG);
+ TEST_I_F(signed char, unsigned char, float, FLT_MANT_DIG, FLT_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, float, FLT_MANT_DIG, FLT_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, float, FLT_MANT_DIG, FLT_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, float, FLT_MANT_DIG, FLT_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, float, FLT_MANT_DIG, FLT_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee-timode.c
new file mode 100644
index 0000000..59a7a8c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float128 type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee.c
new file mode 100644
index 0000000..e1aeab0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-ieee.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float128. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float128, FLT128_MANT_DIG, FLT128_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
index 493dee8..ddeef86 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
@@ -9,10 +9,11 @@
#include "fp-int-convert.h"
#define FLOAT128_MANT_DIG 113
+#define FLOAT128_MAX_EXP 16384
int
main (void)
{
- TEST_I_F(TItype, UTItype, __float128, FLOAT128_MANT_DIG);
+ TEST_I_F(TItype, UTItype, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
index bc5e5ad..4adff79 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
@@ -6,14 +6,15 @@
#include "fp-int-convert.h"
#define FLOAT128_MANT_DIG 113
+#define FLOAT128_MAX_EXP 16384
int
main (void)
{
- TEST_I_F(signed char, unsigned char, __float128, FLOAT128_MANT_DIG);
- TEST_I_F(signed short, unsigned short, __float128, FLOAT128_MANT_DIG);
- TEST_I_F(signed int, unsigned int, __float128, FLOAT128_MANT_DIG);
- TEST_I_F(signed long, unsigned long, __float128, FLOAT128_MANT_DIG);
- TEST_I_F(signed long long, unsigned long long, __float128, FLOAT128_MANT_DIG);
+ TEST_I_F(signed char, unsigned char, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, __float128, FLOAT128_MANT_DIG, FLOAT128_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x-timode.c
new file mode 100644
index 0000000..682dcdc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float128x type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float128, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x.c
new file mode 100644
index 0000000..a09ed5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128x.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float128x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float128x } */
+/* { dg-require-effective-target float128x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float128x, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float128x, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float128x, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float128x, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float128x, FLT128X_MANT_DIG, FLT128X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16-timode.c
new file mode 100644
index 0000000..f64f1d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float16 type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16.c
new file mode 100644
index 0000000..92e976f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float16. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float16, FLT16_MANT_DIG, FLT16_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32-timode.c
new file mode 100644
index 0000000..c248497
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float32 type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32.c
new file mode 100644
index 0000000..09847d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float32. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32 } */
+/* { dg-require-effective-target float32_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float32, FLT32_MANT_DIG, FLT32_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x-timode.c
new file mode 100644
index 0000000..f08bd007
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float32x type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float32, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x.c
new file mode 100644
index 0000000..8ea2eaf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float32x.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float32x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float32x, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float32x, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float32x, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float32x, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float32x, FLT32X_MANT_DIG, FLT32X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64-timode.c
new file mode 100644
index 0000000..ecefa81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float64 type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64.c
new file mode 100644
index 0000000..196d611
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float64. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64 } */
+/* { dg-require-effective-target float64_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float64, FLT64_MANT_DIG, FLT64_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x-timode.c
new file mode 100644
index 0000000..7b06a80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x-timode.c
@@ -0,0 +1,16 @@
+/* Test floating-point conversions. _Float64x type with TImode. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(TItype, UTItype, _Float64, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x.c
new file mode 100644
index 0000000..e103a5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float64x.c
@@ -0,0 +1,20 @@
+/* Test floating-point conversions. Standard types and _Float64x. */
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float64x_runtime } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+ TEST_I_F(signed char, unsigned char, _Float64x, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, _Float64x, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, _Float64x, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, _Float64x, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, _Float64x, FLT64X_MANT_DIG, FLT64X_MAX_EXP);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c
index 7600994..9c94438 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c
@@ -7,10 +7,11 @@
#include "fp-int-convert.h"
#define FLOAT80_MANT_DIG 64
+#define FLOAT80_MAX_EXP 16384
int
main (void)
{
- TEST_I_F(TItype, UTItype, __float80, FLOAT80_MANT_DIG);
+ TEST_I_F(TItype, UTItype, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
index 3e25f90..e545613 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
@@ -6,14 +6,15 @@
#include "fp-int-convert.h"
#define FLOAT80_MANT_DIG 64
+#define FLOAT80_MAX_EXP 16384
int
main (void)
{
- TEST_I_F(signed char, unsigned char, __float80, FLOAT80_MANT_DIG);
- TEST_I_F(signed short, unsigned short, __float80, FLOAT80_MANT_DIG);
- TEST_I_F(signed int, unsigned int, __float80, FLOAT80_MANT_DIG);
- TEST_I_F(signed long, unsigned long, __float80, FLOAT80_MANT_DIG);
- TEST_I_F(signed long long, unsigned long long, __float80, FLOAT80_MANT_DIG);
+ TEST_I_F(signed char, unsigned char, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, __float80, FLOAT80_MANT_DIG, FLOAT80_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c
index bb189a3..d8e5197 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c
@@ -9,10 +9,10 @@
int
main (void)
{
- TEST_I_F(signed char, unsigned char, long double, LDBL_MANT_DIG);
- TEST_I_F(signed short, unsigned short, long double, LDBL_MANT_DIG);
- TEST_I_F(signed int, unsigned int, long double, LDBL_MANT_DIG);
- TEST_I_F(signed long, unsigned long, long double, LDBL_MANT_DIG);
- TEST_I_F(signed long long, unsigned long long, long double, LDBL_MANT_DIG);
+ TEST_I_F(signed char, unsigned char, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
+ TEST_I_F(signed short, unsigned short, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
+ TEST_I_F(signed int, unsigned int, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
+ TEST_I_F(signed long, unsigned long, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
+ TEST_I_F(signed long long, unsigned long long, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c
index 3a60d01..0ef3e54 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c
@@ -9,13 +9,13 @@
int
main (void)
{
- TEST_I_F(TItype, UTItype, float, FLT_MANT_DIG);
- TEST_I_F(TItype, UTItype, double, DBL_MANT_DIG);
+ TEST_I_F(TItype, UTItype, float, FLT_MANT_DIG, FLT_MAX_EXP);
+ TEST_I_F(TItype, UTItype, double, DBL_MANT_DIG, DBL_MAX_EXP);
/* Disable the long double tests when using IBM Extended Doubles.
They have variable precision, but constants calculated by gcc's
real.c assume fixed precision. */
#if DBL_MANT_DIG != LDBL_MANT_DIG && LDBL_MANT_DIG != 106
- TEST_I_F(TItype, UTItype, long double, LDBL_MANT_DIG);
+ TEST_I_F(TItype, UTItype, long double, LDBL_MANT_DIG, LDBL_MAX_EXP);
#endif
exit (0);
}
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert.h b/gcc/testsuite/gcc.dg/torture/fp-int-convert.h
index 8ac9c3d..59773e3 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert.h
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert.h
@@ -15,20 +15,21 @@ typedef long TItype;
typedef unsigned long UTItype;
#endif
-/* TEST_I_F(I, U, F, P) tests conversions between the pair of signed
- and unsigned integer types I and U and the floating-point type F,
- where P is the binary precision of the floating point type. We
- test conversions of the values 0, 1, 0x7...f, 0x8...0, 0xf...f. We
- also test conversions of values half way between two
- representable values (rounding both ways), just above half way, and
- just below half way. */
-#define TEST_I_F(I, U, F, P) \
+/* TEST_I_F(I, U, F, P, M) tests conversions between the pair of
+ signed and unsigned integer types I and U and the floating-point
+ type F, where P is the binary precision of the floating point type
+ and M is the MAX_EXP value for that type (so 2^M overflows, 2^(M-1)
+ does not). We test conversions of the values 0, 1, 0x7...f,
+ 0x8...0, 0xf...f. We also test conversions of values half way
+ between two representable values (rounding both ways), just above
+ half way, and just below half way. */
+#define TEST_I_F(I, U, F, P, M) \
do { \
TEST_I_F_VAL (I, F, (I)0, 1); \
TEST_I_F_VAL (I, F, (I)1, 1); \
TEST_I_F_VAL (I, F, (I)(((U)~(U)0) >> 1), P_OK1 (P, I)); \
- TEST_I_F_VAL (I, F, (I)(U)~(((U)~(U)0) >> 1), 1); \
- TEST_I_F_VAL (I, F, (I)(U)~(U)0, P_OK (P, I)); \
+ TEST_I_F_VAL (I, F, (I)(U)~(((U)~(U)0) >> 1), M_OK1 (M, I)); \
+ TEST_I_F_VAL (I, F, (I)(U)~(U)0, 1); \
TEST_I_F_VAL (I, F, HVAL0S (P, I), P_OK (P, I)); \
TEST_I_F_VAL (I, F, HVAL0S (P, I) + 1, P_OK (P, I)); \
TEST_I_F_VAL (I, F, HVAL0S (P, I) - 1, P_OK (P, I)); \
@@ -44,7 +45,7 @@ do { \
TEST_I_F_VAL (U, F, (U)0, 1); \
TEST_I_F_VAL (U, F, (U)1, 1); \
TEST_I_F_VAL (U, F, (U)(((U)~(U)0) >> 1), P_OK1 (P, U)); \
- TEST_I_F_VAL (U, F, (U)~(((U)~(U)0) >> 1), 1); \
+ TEST_I_F_VAL (U, F, (U)~(((U)~(U)0) >> 1), M_OK1 (M, U)); \
TEST_I_F_VAL (U, F, (U)~(U)0, P_OK (P, U)); \
TEST_I_F_VAL (U, F, HVAL0U (P, U), P_OK (P, U)); \
TEST_I_F_VAL (U, F, HVAL0U (P, U) + 1, P_OK (P, U)); \
@@ -56,6 +57,7 @@ do { \
#define P_OK(P, T) ((P) >= sizeof(T) * CHAR_BIT)
#define P_OK1(P, T) ((P) >= sizeof(T) * CHAR_BIT - 1)
+#define M_OK1(M, T) ((M) > sizeof(T) * CHAR_BIT - 1)
#define HVAL0U(P, U) (U)(P_OK (P, U) \
? (U)1 \
: (((U)1 << (sizeof(U) * CHAR_BIT - 1)) \