From 53605f35cddd3c353ae9f7db1aaf9565a08826ea Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Fri, 24 Jun 2016 21:55:40 +0000 Subject: [PATCH] rs6000-builtin.def (BU_FLOAT128_2): New #define. [gcc] 2016-06-24 Bill Schmidt * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2): New #define. (BU_FLOAT128_1): Likewise. (FABSQ): Likewise. (COPYSIGNQ): Likewise. (RS6000_BUILTIN_NANQ): Likewise. (RS6000_BUILTIN_NANSQ): Likewise. (RS6000_BUILTIN_INFQ): Likewise. (RS6000_BUILTIN_HUGE_VALQ): Likewise. * config/rs6000/rs6000.c (rs6000_fold_builtin): New prototype. (TARGET_FOLD_BUILTIN): New #define. (rs6000_builtin_mask_calculate): Add TARGET_FLOAT128 entry. (rs6000_invalid_builtin): Add handling for RS6000_BTM_FLOAT128. (rs6000_fold_builtin): New target hook implementation, handling folding of 128-bit NaNs and infinities. (rs6000_init_builtins): Initialize const_str_type_node; ensure all entries are filled in to avoid problems during bootstrap self-test; define builtins for 128-bit NaNs and infinities. (rs6000_opt_mask): Add entry for float128. * config/rs6000/rs6000.h (RS6000_BTM_FLOAT128): New #define. (RS6000_BTM_COMMON): Include RS6000_BTM_FLOAT128. (rs6000_builtin_type_index): Add RS6000_BTI_const_str. (const_str_type_node): New #define. * config/rs6000/rs6000.md (copysign3 for IEEE128): Convert to a define_expand that dispatches to either copysign3_soft or copysign3_hard. (copysign3_hard): Rename from copysign3. (copysign3_soft): New define_insn. * doc/extend.texi: Document new builtins. [gcc/testsuite] 2016-06-24 Bill Schmidt * gcc.target/powerpc/abs128-1.c: New. * gcc.target/powerpc/copysign128-1.c: New. * gcc.target/powerpc/inf128-1.c: New. * gcc.target/powerpc/nan128-1.c: New. From-SVN: r237774 --- gcc/ChangeLog | 31 ++++++++ gcc/config/rs6000/rs6000-builtin.def | 33 ++++++++ gcc/config/rs6000/rs6000.c | 73 +++++++++++++++++- gcc/config/rs6000/rs6000.h | 6 +- gcc/config/rs6000/rs6000.md | 32 +++++++- gcc/doc/extend.texi | 34 ++++++++ gcc/testsuite/ChangeLog | 7 ++ gcc/testsuite/gcc.target/powerpc/abs128-1.c | 61 +++++++++++++++ .../gcc.target/powerpc/copysign128-1.c | 58 ++++++++++++++ gcc/testsuite/gcc.target/powerpc/inf128-1.c | 55 +++++++++++++ gcc/testsuite/gcc.target/powerpc/nan128-1.c | 77 +++++++++++++++++++ 11 files changed, 464 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/abs128-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/copysign128-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/inf128-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/nan128-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf1764ce792..a88fd1824f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2016-06-24 Bill Schmidt + + * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2): New #define. + (BU_FLOAT128_1): Likewise. + (FABSQ): Likewise. + (COPYSIGNQ): Likewise. + (RS6000_BUILTIN_NANQ): Likewise. + (RS6000_BUILTIN_NANSQ): Likewise. + (RS6000_BUILTIN_INFQ): Likewise. + (RS6000_BUILTIN_HUGE_VALQ): Likewise. + * config/rs6000/rs6000.c (rs6000_fold_builtin): New prototype. + (TARGET_FOLD_BUILTIN): New #define. + (rs6000_builtin_mask_calculate): Add TARGET_FLOAT128 entry. + (rs6000_invalid_builtin): Add handling for RS6000_BTM_FLOAT128. + (rs6000_fold_builtin): New target hook implementation, handling + folding of 128-bit NaNs and infinities. + (rs6000_init_builtins): Initialize const_str_type_node; ensure all + entries are filled in to avoid problems during bootstrap + self-test; define builtins for 128-bit NaNs and infinities. + (rs6000_opt_mask): Add entry for float128. + * config/rs6000/rs6000.h (RS6000_BTM_FLOAT128): New #define. + (RS6000_BTM_COMMON): Include RS6000_BTM_FLOAT128. + (rs6000_builtin_type_index): Add RS6000_BTI_const_str. + (const_str_type_node): New #define. + * config/rs6000/rs6000.md (copysign3 for IEEE128): Convert + to a define_expand that dispatches to either copysign3_soft + or copysign3_hard. + (copysign3_hard): Rename from copysign3. + (copysign3_soft): New define_insn. + * doc/extend.texi: Document new builtins. + 2016-06-24 Jakub Jelinek * cfgloop.c (flow_loop_dump): Cast nit to uint64_t and print it using diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index a52da3bfb27..533f77120d3 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -652,6 +652,22 @@ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +/* IEEE 128-bit floating-point builtins. */ +#define BU_FLOAT128_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_FLOAT128_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ /* Miscellaneous builtins for instructions added in ISA 3.0. These instructions don't require either the DFP or VSX options, just the basic @@ -1814,6 +1830,11 @@ BU_P9V_OVERLOAD_1 (VPRTYBD, "vprtybd") BU_P9V_OVERLOAD_1 (VPRTYBQ, "vprtybq") BU_P9V_OVERLOAD_1 (VPRTYBW, "vprtybw") +/* 1 argument IEEE 128-bit floating-point functions. */ +BU_FLOAT128_1 (FABSQ, "fabsq", CONST, abskf2) + +/* 2 argument IEEE 128-bit floating-point functions. */ +BU_FLOAT128_2 (COPYSIGNQ, "copysignq", CONST, copysignkf3) /* 1 argument crypto functions. */ BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox) @@ -2191,6 +2212,18 @@ BU_SPECIAL_X (RS6000_BUILTIN_CPU_IS, "__builtin_cpu_is", BU_SPECIAL_X (RS6000_BUILTIN_CPU_SUPPORTS, "__builtin_cpu_supports", RS6000_BTM_ALWAYS, RS6000_BTC_MISC) +BU_SPECIAL_X (RS6000_BUILTIN_NANQ, "__builtin_nanq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_NANSQ, "__builtin_nansq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_INFQ, "__builtin_infq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_HUGE_VALQ, "__builtin_huge_valq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + /* Darwin CfString builtin. */ BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS, RS6000_BTC_MISC) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4762c21b7a1..4c239613b89 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1328,6 +1328,7 @@ static bool rs6000_secondary_reload_move (enum rs6000_reg_type, bool); rtl_opt_pass *make_pass_analyze_swaps (gcc::context*); static bool rs6000_keep_leaf_when_profiled () __attribute__ ((unused)); +static tree rs6000_fold_builtin (tree, int, tree *, bool); /* Hash table stuff for keeping track of TOC entries. */ @@ -1602,6 +1603,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_BUILTIN_DECL #define TARGET_BUILTIN_DECL rs6000_builtin_decl +#undef TARGET_FOLD_BUILTIN +#define TARGET_FOLD_BUILTIN rs6000_fold_builtin + #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin @@ -3682,7 +3686,8 @@ rs6000_builtin_mask_calculate (void) | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0) - | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0)); + | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0) + | ((TARGET_FLOAT128) ? RS6000_BTM_FLOAT128 : 0)); } /* Implement TARGET_MD_ASM_ADJUST. All asm statements are considered @@ -15503,11 +15508,57 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode) " -mlong-double-128 options", name); else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0) error ("Builtin function %s requires the -mhard-float option", name); + else if ((fnmask & RS6000_BTM_FLOAT128) != 0) + error ("Builtin function %s requires the -mfloat128 option", name); else error ("Builtin function %s is not supported with the current options", name); } +/* Target hook for early folding of built-ins, shamelessly stolen + from ia64.c. */ + +static tree +rs6000_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, + tree *args, bool ignore ATTRIBUTE_UNUSED) +{ + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) + { + enum rs6000_builtins fn_code + = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); + switch (fn_code) + { + case RS6000_BUILTIN_NANQ: + case RS6000_BUILTIN_NANSQ: + { + tree type = TREE_TYPE (TREE_TYPE (fndecl)); + const char *str = c_getstr (*args); + int quiet = fn_code == RS6000_BUILTIN_NANQ; + REAL_VALUE_TYPE real; + + if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) + return build_real (type, real); + return NULL_TREE; + } + case RS6000_BUILTIN_INFQ: + case RS6000_BUILTIN_HUGE_VALQ: + { + tree type = TREE_TYPE (TREE_TYPE (fndecl)); + REAL_VALUE_TYPE inf; + real_inf (&inf); + return build_real (type, inf); + } + default: + break; + } + } +#ifdef SUBTARGET_FOLD_BUILTIN + return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore); +#else + return NULL_TREE; +#endif +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient (and in mode MODE if that's convenient). @@ -15762,6 +15813,10 @@ rs6000_init_builtins (void) opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node); opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4); + const_str_type_node + = build_pointer_type (build_qualified_type (char_type_node, + TYPE_QUAL_CONST)); + /* We use V1TI mode as a special container to hold __int128_t items that must live in VSX registers. */ if (intTI_type_node) @@ -15824,6 +15879,12 @@ rs6000_init_builtins (void) lang_hooks.types.register_builtin_type (ibm128_float_type_node, "__ibm128"); } + else + { + /* All types must be nonzero, or self-test barfs during bootstrap. */ + ieee128_float_type_node = long_double_type_node; + ibm128_float_type_node = long_double_type_node; + } /* Initialize the modes for builtin_function_type, mapping a machine mode to tree type node. */ @@ -15965,6 +16026,15 @@ rs6000_init_builtins (void) if (TARGET_EXTRA_BUILTINS || TARGET_SPE || TARGET_PAIRED_FLOAT) rs6000_common_init_builtins (); + ftype = build_function_type_list (ieee128_float_type_node, + const_str_type_node, NULL_TREE); + def_builtin ("__builtin_nanq", ftype, RS6000_BUILTIN_NANQ); + def_builtin ("__builtin_nansq", ftype, RS6000_BUILTIN_NANSQ); + + ftype = build_function_type_list (ieee128_float_type_node, NULL_TREE); + def_builtin ("__builtin_infq", ftype, RS6000_BUILTIN_INFQ); + def_builtin ("__builtin_huge_valq", ftype, RS6000_BUILTIN_HUGE_VALQ); + ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode, RS6000_BUILTIN_RECIP, "__builtin_recipdiv"); def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP); @@ -35562,6 +35632,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] = { "hard-dfp", RS6000_BTM_DFP, false, false }, { "hard-float", RS6000_BTM_HARD_FLOAT, false, false }, { "long-double-128", RS6000_BTM_LDBL128, false, false }, + { "float128", RS6000_BTM_FLOAT128, false, false }, }; /* Option variables that we want to support inside attribute((target)) and diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d3cba82748b..604d560718d 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2709,6 +2709,7 @@ extern int frame_pointer_needed; #define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ #define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */ #define RS6000_BTM_64BIT MASK_64BIT /* 64-bit addressing. */ +#define RS6000_BTM_FLOAT128 MASK_P9_VECTOR /* IEEE 128-bit float. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ | RS6000_BTM_VSX \ @@ -2725,7 +2726,8 @@ extern int frame_pointer_needed; | RS6000_BTM_CELL \ | RS6000_BTM_DFP \ | RS6000_BTM_HARD_FLOAT \ - | RS6000_BTM_LDBL128) + | RS6000_BTM_LDBL128 \ + | RS6000_BTM_FLOAT128) /* Define builtin enum index. */ @@ -2829,6 +2831,7 @@ enum rs6000_builtin_type_index RS6000_BTI_void, /* void_type_node */ RS6000_BTI_ieee128_float, /* ieee 128-bit floating point */ RS6000_BTI_ibm128_float, /* IBM 128-bit floating point */ + RS6000_BTI_const_str, /* pointer to const char * */ RS6000_BTI_MAX }; @@ -2885,6 +2888,7 @@ enum rs6000_builtin_type_index #define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void]) #define ieee128_float_type_node (rs6000_builtin_types[RS6000_BTI_ieee128_float]) #define ibm128_float_type_node (rs6000_builtin_types[RS6000_BTI_ibm128_float]) +#define const_str_type_node (rs6000_builtin_types[RS6000_BTI_const_str]) extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX]; extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3825cc011d6..5a5635ab245 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -13326,7 +13326,25 @@ "xssqrtqp %0,%1" [(set_attr "type" "vecdiv")]) -(define_insn "copysign3" +(define_expand "copysign3" + [(use (match_operand:IEEE128 0 "altivec_register_operand")) + (use (match_operand:IEEE128 1 "altivec_register_operand")) + (use (match_operand:IEEE128 2 "altivec_register_operand"))] + "FLOAT128_IEEE_P (mode)" +{ + if (TARGET_FLOAT128_HW) + emit_insn (gen_copysign3_hard (operands[0], operands[1], + operands[2])); + else + { + rtx tmp = gen_reg_rtx (mode); + emit_insn (gen_copysign3_soft (operands[0], operands[1], + operands[2], tmp)); + } + DONE; +}) + +(define_insn "copysign3_hard" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") (unspec:IEEE128 [(match_operand:IEEE128 1 "altivec_register_operand" "v") @@ -13336,6 +13354,18 @@ "xscpsgnqp %0,%2,%1" [(set_attr "type" "vecsimple")]) +(define_insn "copysign3_soft" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v") + (match_operand:IEEE128 3 "altivec_register_operand" "+v")] + UNSPEC_COPYSIGN))] + "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" + [(set_attr "type" "veccomplex") + (set_attr "length" "8")]) + (define_insn "neg2_hw" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") (neg:IEEE128 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 604b441d184..9c8ea837456 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -14782,6 +14782,40 @@ The @code{__builtin_ppc_mftb} function always generates one instruction and returns the Time Base Register value as an unsigned long, throwing away the most significant word on 32-bit environments. +Additional built-in functions are available for the 64-bit PowerPC +family of processors, for efficient use of 128-bit floating point +(@code{__float128}) values. + +The following floating-point built-in functions are available with +@code{-mfloat128} and Altivec support. All of them implement the +function that is part of the name. + +@smallexample +__float128 __builtin_fabsq (__float128) +__float128 __builtin_copysignq (__float128, __float128) +@end smallexample + +The following built-in functions are available with @code{-mfloat128} +and Altivec support. + +@table @code +@item __float128 __builtin_infq (void) +Similar to @code{__builtin_inf}, except the return type is @code{__float128}. +@findex __builtin_infq + +@item __float128 __builtin_huge_valq (void) +Similar to @code{__builtin_huge_val}, except the return type is @code{__float128}. +@findex __builtin_huge_valq + +@item __float128 __builtin_nanq (void) +Similar to @code{__builtin_nan}, except the return type is @code{__float128}. +@findex __builtin_nanq + +@item __float128 __builtin_nansq (void) +Similar to @code{__builtin_nans}, except the return type is @code{__float128}. +@findex __builtin_nansq +@end table + The following built-in functions are available for the PowerPC family of processors, starting with ISA 2.06 or later (@option{-mcpu=power7} or @option{-mpopcntd}): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bbb2214a7a0..f373b0e2774 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-06-24 Bill Schmidt + + * gcc.target/powerpc/abs128-1.c: New. + * gcc.target/powerpc/copysign128-1.c: New. + * gcc.target/powerpc/inf128-1.c: New. + * gcc.target/powerpc/nan128-1.c: New. + 2016-06-24 Eric Botcazou * gfortran.dg/pr71642.f90: New test. diff --git a/gcc/testsuite/gcc.target/powerpc/abs128-1.c b/gcc/testsuite/gcc.target/powerpc/abs128-1.c new file mode 100644 index 00000000000..e4b0c291e85 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/abs128-1.c @@ -0,0 +1,61 @@ +/* { dg-do run { target { powerpc64*-*-* && vmx_hw } } } */ +/* { dg-options "-mfloat128" } */ + +void abort (); + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +int +main (int argc, int *argv[]) +{ + ieee854_float128 x, z; + + x.nan.negative = 1; + x.nan.exponent = 0x22; + x.nan.quiet_nan = 0; + x.nan.mant_high = 0x1234; + x.nan.mant_low = 0xabcdef; + + z.value = __builtin_fabsq (x.value); + + if (z.nan.negative != 0 + || z.nan.exponent != 0x22 + || z.nan.quiet_nan != 0 + || z.nan.mant_high != 0x1234 + || z.nan.mant_low != 0xabcdef) + abort (); + + z.value = __builtin_fabsq (z.value); + + if (z.nan.negative != 0 + || z.nan.exponent != 0x22 + || z.nan.quiet_nan != 0 + || z.nan.mant_high != 0x1234 + || z.nan.mant_low != 0xabcdef) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/copysign128-1.c b/gcc/testsuite/gcc.target/powerpc/copysign128-1.c new file mode 100644 index 00000000000..0d7b7e546fb --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/copysign128-1.c @@ -0,0 +1,58 @@ +/* { dg-do run { target { powerpc64*-*-* && vmx_hw } } } */ +/* { dg-options "-mfloat128" } */ + +void abort (); + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +int +main (int argc, int *argv[]) +{ + ieee854_float128 x, y, z; + + x.nan.negative = 0; + x.nan.exponent = 0x22; + x.nan.quiet_nan = 0; + x.nan.mant_high = 0x1234; + x.nan.mant_low = 0xabcdef; + + y.nan.negative = 1; + y.nan.exponent = 0; + y.nan.quiet_nan = 0; + y.nan.mant_high = 0; + y.nan.mant_low = 0; + + z.value = __builtin_copysignq (x.value, y.value); + + if (z.nan.negative != 1 + || z.nan.exponent != 0x22 + || z.nan.quiet_nan != 0 + || z.nan.mant_high != 0x1234 + || z.nan.mant_low != 0xabcdef) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/inf128-1.c b/gcc/testsuite/gcc.target/powerpc/inf128-1.c new file mode 100644 index 00000000000..b8df25ba82e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/inf128-1.c @@ -0,0 +1,55 @@ +/* { dg-do run { target { powerpc64*-*-* && vmx_hw } } } */ +/* { dg-options "-mfloat128" } */ + +void abort (); + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +int +main (int argc, int *argv[]) +{ + ieee854_float128 y; + + y.value = __builtin_infq (); + + if (y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 0 + || y.nan.mant_high != 0 + || y.nan.mant_low != 0) + abort (); + + y.value = __builtin_huge_valq (); + + if (y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 0 + || y.nan.mant_high != 0 + || y.nan.mant_low != 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/nan128-1.c b/gcc/testsuite/gcc.target/powerpc/nan128-1.c new file mode 100644 index 00000000000..6fc00ecade0 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/nan128-1.c @@ -0,0 +1,77 @@ +/* { dg-do run { target { powerpc64*-*-* && vmx_hw } } } */ +/* { dg-options "-mfloat128" } */ + +#include + +void abort (); + +typedef unsigned long long int uint64_t; + +typedef union +{ + __float128 value; + + struct + { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned negative:1; + unsigned exponent:15; + unsigned quiet_nan:1; + uint64_t mant_high:47; + uint64_t mant_low:64; +#else + uint64_t mant_low:64; + uint64_t mant_high:47; + unsigned quiet_nan:1; + unsigned exponent:15; + unsigned negative:1; +#endif + } nan; + +} ieee854_float128; + +int +main (int argc, int *argv[]) +{ + ieee854_float128 y; + + y.value = __builtin_nanq ("1"); + + if (y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 1 + || y.nan.mant_high != 0 + || y.nan.mant_low != 1) + abort (); + + y.value = __builtin_nanq ("0x2ab3c"); + + if (y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 1 + || y.nan.mant_high != 0 + || y.nan.mant_low != 0x2ab3c) + abort (); + + y.value = __builtin_nansq ("1"); + + if ( + y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 0 + || y.nan.mant_high != 0 + || y.nan.mant_low != 1 + ) + abort (); + + y.value = __builtin_nansq ("0x2ab3c"); + + if (y.nan.negative != 0 + || y.nan.exponent != 0x7fff + || y.nan.quiet_nan != 0 + || y.nan.mant_high != 0 + || y.nan.mant_low != 0x2ab3c) + abort (); + + return 0; +} -- 2.30.2