This patch enables -mfloat128 to be the default on PowerPC Linux VSX systems.
This patch depends on the libquadmatch/81848 patch being approved and installed: https://gcc.gnu.org/ml/gcc-patches/2017-08/msg00977.html In this patch, I removed the old undocumented -mfloat128-type switch, and made the default to be on for PowerPC Linux systems. The default is off for other systems (such as AIX) because they don't build the float128 emulation routines in libgcc. This patch also supersedes the patch for target/70589 that was previously submitted. It includes the changes for that bug to enable/disable -mfloat128 via target pragmas/attributes with the exception that the option -mfloat128-type is now deleted: https://gcc.gnu.org/ml/gcc-patches/2017-08/msg00894.html I fixed up all of the float128 tests to remove the explict -mfloat128 option and add -mno-float128 as needed. I've checked this on a big endian power7 system (both 32-bit and 64-bit) and a little endian power8 system. It bootstrapped fine and had no regressions in the test suite. I also built the latest boost library and got the same results for the pre -mfloat128 compiler and the compiler with -mfloat128 as the default, and there were no changes. I also built and ran spec 2006 FP tests with the two compilers, and there no changes in runtime of the tests. Can I check this into the trunk once the patch for 81848 has been applied? [gcc] 2017-08-16 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/81872 * config/rs6000/rs6000-cpus.def (OTHER_VSX_VECTOR_MASKS): Delete OPTION_MASK_FLOAT128_TYPE. (POWERPC_MASKS): Likewise. * config/rs6000/rs6000.opt (TARGET_FLOAT128_ENABLE_TYPE): Make this a variable instead of a target switch. (-mfloat128-type): Delete switch. * config/rs6000/rs6000.c (rs6000_option_override_internal): Set -mfloat128 by default on Linux VSX systems. Remove support for an explicit -mfloat128-type option. Rework how -mfloat128-hardware is set on ISA 3.0 systems. Even if -mno-float128 is used, enable the IEEE 128-bit type support internally. (rs6000_opt_masks): Delete -mfloat128-type. * config/rs6000/rs6000.h (MASK_FLOAT128_TYPE): Delete. (MASK_FLOAT128_KEYWORD): Define. (RS6000_BTM_FLOAT128): Use the mask for -mfloat128 instead of -mfloat128-type to signal we should build the IEEE 128-bit built-in functions. The function rs6000_builtin_mask_calculate in rs6000.c still uses TARGET_FLOAT128_ENABLE_TYPE to determine whether to enable the built-in functions or not. * doc/invoke.texi (RS/6000 and PowerPC Options): Update -mfloat128 and -mfloat128-hardware documentation. PR target/70589 * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Make the real keyword for IEEE 128-bit be __ieee128 for VSX runs, and define __float128 to be __ieee128 if -mfloat128 is used or a float128 target attribute/pragma is used. Enable _Float128 all of the time. (rs6000_cpu_cpp_builtins): Likewise. * config/rs6000/rs6000.c (rs6000_init_builtins): Likewise. (rs6000_floatn_mode): Likewise. (rs6000_opt_masks): Likewise. [gcc/testsuite] 2017-08-16 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/81872 * gcc.target/powerpc/float128-1.c: Change float128 tests to assume -mfloat128 is on by default. Explicitly use -mno-float128 to test when the __float128 keyword should not be available. Use -mvsx, -mpower8-vector, or -mpower9-vector instead of -mcpu=power7/8/9 in many cases. * gcc.target/powerpc/float128-2.c: Likewise. * gcc.target/powerpc/float128-cmp.c: Likewise. * gcc.target/powerpc/float128-complex-1.c: Likewise. * gcc.target/powerpc/float128-complex-2.c: Likewise. * gcc.target/powerpc/float128-hw.c: Likewise. * gcc.target/powerpc/float128-mix.c: Likewise. * gcc.target/powerpc/float128-type-1.c: Likewise. * gcc.target/powerpc/float128-type-2.c: Likewise. PR target/70589 * gcc.target/powerpc/float128-3.c: New test. * gcc.target/powerpc/float128-4.c: Likewise. * gcc.target/powerpc/float128-5.c: Likewise. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000-cpus.def =================================================================== --- gcc/config/rs6000/rs6000-cpus.def (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 251056) +++ gcc/config/rs6000/rs6000-cpus.def (.../gcc/config/rs6000) (working copy) @@ -92,7 +92,6 @@ #define OTHER_VSX_VECTOR_MASKS (OTHER_P8_VECTOR_MASKS \ | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ | OPTION_MASK_FLOAT128_KEYWORD \ - | OPTION_MASK_FLOAT128_TYPE \ | OPTION_MASK_P8_VECTOR \ | OPTION_MASK_VSX_TIMODE) @@ -119,7 +118,6 @@ | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ | OPTION_MASK_FLOAT128_HW \ | OPTION_MASK_FLOAT128_KEYWORD \ - | OPTION_MASK_FLOAT128_TYPE \ | OPTION_MASK_FPRND \ | OPTION_MASK_HTM \ | OPTION_MASK_ISEL \ Index: gcc/config/rs6000/rs6000.opt =================================================================== --- gcc/config/rs6000/rs6000.opt (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 251056) +++ gcc/config/rs6000/rs6000.opt (.../gcc/config/rs6000) (working copy) @@ -100,6 +100,14 @@ HOST_WIDE_INT rs6000_builtin_mask TargetVariable unsigned int rs6000_debug +;; Whether to enable the -mfloat128 stuff without necessarily enabling the +;; __float128 keyword. +TargetSave +unsigned char x_TARGET_FLOAT128_TYPE + +Variable +unsigned char TARGET_FLOAT128_TYPE + ;; This option existed in the past, but now is always on. mpowerpc Target RejectNegative Undocumented Ignore @@ -590,14 +598,6 @@ mmodulo Target Undocumented Report Mask(MODULO) Var(rs6000_isa_flags) Generate the integer modulo instructions. -; We want to enable the internal support for the IEEE 128-bit floating point -; type without necessarily enabling the __float128 keyword. This is to allow -; Boost and other libraries that know about __float128 to work until the -; official library support is finished. -mfloat128-type -Target Undocumented Mask(FLOAT128_TYPE) Var(rs6000_isa_flags) -Allow the IEEE 128-bit types without requiring the __float128 keyword. - mfloat128 Target Report Mask(FLOAT128_KEYWORD) Var(rs6000_isa_flags) Enable IEEE 128-bit floating point via the __float128 keyword. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 251056) +++ gcc/config/rs6000/rs6000.c (.../gcc/config/rs6000) (working copy) @@ -4611,72 +4611,42 @@ rs6000_option_override_internal (bool gl #endif /* Enable the default support for IEEE 128-bit floating point on Linux VSX - sytems, but don't enable the __float128 keyword. */ - if (TARGET_VSX && TARGET_LONG_DOUBLE_128 - && (TARGET_FLOAT128_ENABLE_TYPE || TARGET_IEEEQUAD) - && ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_TYPE) == 0)) - rs6000_isa_flags |= OPTION_MASK_FLOAT128_TYPE; + sytems. In GCC 7, we would enable the the IEEE 128-bit floating point + infrastructure (-mfloat128-type) but not enable the actual __float128 type + unless the user used the explicit -mfloat128. In GCC 8, we enable both + the keyword as well as the type. */ + TARGET_FLOAT128_TYPE = TARGET_FLOAT128_ENABLE_TYPE && TARGET_VSX; /* IEEE 128-bit floating point requires VSX support. */ - if (!TARGET_VSX) + if (TARGET_FLOAT128_KEYWORD) { - if (TARGET_FLOAT128_KEYWORD) + if (!TARGET_VSX) { if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0) error ("-mfloat128 requires VSX support"); - rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE - | OPTION_MASK_FLOAT128_KEYWORD + TARGET_FLOAT128_TYPE = 0; + rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_KEYWORD | OPTION_MASK_FLOAT128_HW); } - - else if (TARGET_FLOAT128_TYPE) + else if (!TARGET_FLOAT128_TYPE) { - if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_TYPE) != 0) - error ("-mfloat128-type requires VSX support"); - - rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE - | OPTION_MASK_FLOAT128_KEYWORD - | OPTION_MASK_FLOAT128_HW); + TARGET_FLOAT128_TYPE = 1; + warning (0, "The -mfloat128 option may not be fully supported"); } } - /* -mfloat128 and -mfloat128-hardware internally require the underlying IEEE - 128-bit floating point support to be enabled. */ - if (!TARGET_FLOAT128_TYPE) - { - if (TARGET_FLOAT128_KEYWORD) - { - if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0) - { - error ("-mfloat128 requires -mfloat128-type"); - rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE - | OPTION_MASK_FLOAT128_KEYWORD - | OPTION_MASK_FLOAT128_HW); - } - else - rs6000_isa_flags |= OPTION_MASK_FLOAT128_TYPE; - } - - if (TARGET_FLOAT128_HW) - { - if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0) - { - error ("-mfloat128-hardware requires -mfloat128-type"); - rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW; - } - else - rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_TYPE - | OPTION_MASK_FLOAT128_KEYWORD - | OPTION_MASK_FLOAT128_HW); - } - } + /* Enable the __float128 keyword under Linux by default. */ + if (TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_KEYWORD + && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) == 0) + rs6000_isa_flags |= OPTION_MASK_FLOAT128_KEYWORD; - /* If we have -mfloat128-type and full ISA 3.0 support, enable - -mfloat128-hardware by default. However, don't enable the __float128 - keyword. If the user explicitly turned on -mfloat128-hardware, enable the - -mfloat128 option as well if it was not already set. */ - if (TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW + /* If we have are supporting the float128 type and full ISA 3.0 support, + enable -mfloat128-hardware by default. However, don't enable the + __float128 keyword if it was explicitly turned off. 64-bit mode is needed + because sometimes the compiler wants to put things in an integer + container, and if we don't have __int128 support, it is impossible. */ + if (TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && TARGET_64BIT && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) == ISA_3_0_MASKS_IEEE && !(rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW)) rs6000_isa_flags |= OPTION_MASK_FLOAT128_HW; @@ -4698,11 +4668,6 @@ rs6000_option_override_internal (bool gl rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW; } - if (TARGET_FLOAT128_HW && !TARGET_FLOAT128_KEYWORD - && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0 - && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) == 0) - rs6000_isa_flags |= OPTION_MASK_FLOAT128_KEYWORD; - /* Print the options after updating the defaults. */ if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags); @@ -4769,10 +4734,12 @@ rs6000_option_override_internal (bool gl unless the altivec ABI was set. This is set by default for 64-bit, but not for 32-bit. */ if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi) - rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC - | OPTION_MASK_FLOAT128_TYPE - | OPTION_MASK_FLOAT128_KEYWORD) - & ~rs6000_isa_flags_explicit); + { + TARGET_FLOAT128_TYPE = 0; + rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC + | OPTION_MASK_FLOAT128_KEYWORD) + & ~rs6000_isa_flags_explicit); + } /* Enable Altivec ABI for AIX -maltivec. */ if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX)) @@ -16868,16 +16835,17 @@ rs6000_init_builtins (void) format that uses a pair of doubles, depending on the switches and defaults. - We do not enable the actual __float128 keyword unless the user explicitly - asks for it, because the library support is not yet complete. - If we don't support for either 128-bit IBM double double or IEEE 128-bit floating point, we need make sure the type is non-zero or else self-test fails during bootstrap. We don't register a built-in type for __ibm128 if the type is the same as long double. Instead we add a #define for __ibm128 in - rs6000_cpu_cpp_builtins to long double. */ + rs6000_cpu_cpp_builtins to long double. + + For IEEE 128-bit floating point, always create the type __ieee128. If the + user used -mfloat128, rs6000-c.c will create a define from __float128 to + __ieee128. */ if (TARGET_LONG_DOUBLE_128 && FLOAT128_IEEE_P (TFmode)) { ibm128_float_type_node = make_node (REAL_TYPE); @@ -16891,24 +16859,10 @@ rs6000_init_builtins (void) else ibm128_float_type_node = long_double_type_node; - if (TARGET_FLOAT128_KEYWORD) + if (TARGET_FLOAT128_TYPE) { ieee128_float_type_node = float128_type_node; lang_hooks.types.register_builtin_type (ieee128_float_type_node, - "__float128"); - } - - else if (TARGET_FLOAT128_TYPE) - { - ieee128_float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (ibm128_float_type_node) = 128; - SET_TYPE_MODE (ieee128_float_type_node, KFmode); - layout_type (ieee128_float_type_node); - - /* If we are not exporting the __float128/_Float128 keywords, we need a - keyword to get the types created. Use __ieee128 as the dummy - keyword. */ - lang_hooks.types.register_builtin_type (ieee128_float_type_node, "__ieee128"); } @@ -32506,11 +32460,14 @@ rs6000_mangle_type (const_tree type) if (type == ieee128_float_type_node) return "U10__float128"; - if (type == ibm128_float_type_node) - return "g"; + if (TARGET_LONG_DOUBLE_128) + { + if (type == long_double_type_node) + return (TARGET_IEEEQUAD) ? "U10__float128" : "g"; - if (type == long_double_type_node && TARGET_LONG_DOUBLE_128) - return (TARGET_IEEEQUAD) ? "U10__float128" : "g"; + if (type == ibm128_float_type_node) + return "g"; + } } /* Mangle IBM extended float long double as `g' (__float128) on @@ -35987,7 +35944,7 @@ rs6000_floatn_mode (int n, bool extended return DFmode; case 64: - if (TARGET_FLOAT128_KEYWORD) + if (TARGET_FLOAT128_TYPE) return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode; else return VOIDmode; @@ -36011,7 +35968,7 @@ rs6000_floatn_mode (int n, bool extended return DFmode; case 128: - if (TARGET_FLOAT128_KEYWORD) + if (TARGET_FLOAT128_TYPE) return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode; else return VOIDmode; @@ -36101,9 +36058,8 @@ static struct rs6000_opt_mask const rs60 { "dlmzb", OPTION_MASK_DLMZB, false, true }, { "efficient-unaligned-vsx", OPTION_MASK_EFFICIENT_UNALIGNED_VSX, false, true }, - { "float128", OPTION_MASK_FLOAT128_KEYWORD, false, false }, - { "float128-type", OPTION_MASK_FLOAT128_TYPE, false, false }, - { "float128-hardware", OPTION_MASK_FLOAT128_HW, false, false }, + { "float128", OPTION_MASK_FLOAT128_KEYWORD, false, true }, + { "float128-hardware", OPTION_MASK_FLOAT128_HW, false, true }, { "fprnd", OPTION_MASK_FPRND, false, true }, { "hard-dfp", OPTION_MASK_DFP, false, true }, { "htm", OPTION_MASK_HTM, false, true }, Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 251056) +++ gcc/config/rs6000/rs6000.h (.../gcc/config/rs6000) (working copy) @@ -643,7 +643,7 @@ extern int rs6000_vector_align[]; #define MASK_DIRECT_MOVE OPTION_MASK_DIRECT_MOVE #define MASK_DLMZB OPTION_MASK_DLMZB #define MASK_EABI OPTION_MASK_EABI -#define MASK_FLOAT128_TYPE OPTION_MASK_FLOAT128_TYPE +#define MASK_FLOAT128_KEYWORD OPTION_MASK_FLOAT128_KEYWORD #define MASK_FPRND OPTION_MASK_FPRND #define MASK_P8_FUSION OPTION_MASK_P8_FUSION #define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT @@ -2590,7 +2590,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_FLOAT128_TYPE /* IEEE 128-bit float. */ +#define RS6000_BTM_FLOAT128 MASK_FLOAT128_KEYWORD /* IEEE 128-bit float. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ | RS6000_BTM_VSX \ Index: gcc/config/rs6000/rs6000-c.c =================================================================== --- gcc/config/rs6000/rs6000-c.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 251056) +++ gcc/config/rs6000/rs6000-c.c (.../gcc/config/rs6000) (working copy) @@ -575,6 +575,18 @@ rs6000_target_modify_macros (bool define 2. If TARGET_ALTIVEC is turned off. */ if ((flags & OPTION_MASK_CRYPTO) != 0) rs6000_define_or_undefine_macro (define_p, "__CRYPTO__"); + if ((flags & OPTION_MASK_FLOAT128_KEYWORD) != 0) + { + rs6000_define_or_undefine_macro (define_p, "__FLOAT128__"); + if (define_p) + rs6000_define_or_undefine_macro (true, "__float128=__ieee128"); + else + rs6000_define_or_undefine_macro (false, "__float128"); + } + /* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or + via the target attribute/pragma. */ + if ((flags & OPTION_MASK_FLOAT128_HW) != 0) + rs6000_define_or_undefine_macro (define_p, "__FLOAT128_HARDWARE__"); /* options from the builtin masks. */ /* Note that RS6000_BTM_PAIRED is enabled only if @@ -602,24 +614,14 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi builtin_define ("__RSQRTE__"); if (TARGET_FRSQRTES) builtin_define ("__RSQRTEF__"); - if (TARGET_FLOAT128_KEYWORD) - builtin_define ("__FLOAT128__"); if (TARGET_FLOAT128_TYPE) builtin_define ("__FLOAT128_TYPE__"); - if (TARGET_FLOAT128_HW) - builtin_define ("__FLOAT128_HARDWARE__"); if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode)) builtin_define ("__ibm128=long double"); #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB builtin_define ("__BUILTIN_CPU_SUPPORTS__"); #endif - /* We needed to create a keyword if -mfloat128-type was used but not -mfloat, - so we used __ieee128. If -mfloat128 was used, create a #define back to - the real keyword in case somebody used it. */ - if (TARGET_FLOAT128_KEYWORD) - builtin_define ("__ieee128=__float128"); - if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM) { /* Define the AltiVec syntactic elements. */ Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/doc) (revision 251056) +++ gcc/doc/invoke.texi (.../gcc/doc) (working copy) @@ -21946,15 +21946,19 @@ Enable/disable the @var{__float128} keyw and use either software emulation for IEEE 128-bit floating point or hardware instructions. -The VSX instruction set (@option{-mvsx}, @option{-mcpu=power7}, or -@option{-mcpu=power8}) must be enabled to use the @option{-mfloat128} -option. The @option{-mfloat128} option only works on PowerPC 64-bit -Linux systems. - -If you use the ISA 3.0 instruction set (@option{-mcpu=power9}), the -@option{-mfloat128} option will also enable the generation of ISA 3.0 -IEEE 128-bit floating point instructions. Otherwise, IEEE 128-bit -floating point will be done with software emulation. +The default for @option{-mfloat128} is enabled on PowerPC Linux +systems using the VSX instruction set, and disabled on other systems. + +The VSX instruction set (@option{-mvsx}, @option{-mcpu=power7}, +@option{-mcpu=power8}) must be enabled to use the IEEE 128-bit +floating point support. The IEEE 128-bit floating point support only +works on PowerPC Linux systems. + +If you use the ISA 3.0 instruction set (@option{-mpower9-vector} or +@option{-mcpu=power9}) on a 64-bit system, the IEEE 128-bit floating +point support will also enable the generation of ISA 3.0 IEEE 128-bit +floating point instructions. Otherwise, IEEE 128-bit floating point +will be done with software emulation. @item -mfloat128-hardware @itemx -mno-float128-hardware @@ -21963,12 +21967,9 @@ floating point will be done with softwar Enable/disable using ISA 3.0 hardware instructions to support the @var{__float128} data type. -If you use @option{-mfloat128-hardware}, it will enable the option -@option{-mfloat128} as well. - -If you select ISA 3.0 instructions with @option{-mcpu=power9}, but do -not use either @option{-mfloat128} or @option{-mfloat128-hardware}, -the IEEE 128-bit floating point support will not be enabled. +The default for @option{-mfloat128-hardware} is enabled on PowerPC +Linux systems using the ISA 3.0 instruction set, and disabled on other +systems. @item -mfloat-gprs=@var{yes/single/double/no} @itemx -mfloat-gprs Index: gcc/testsuite/gcc.target/powerpc/float128-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-1.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-1.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,6 +1,7 @@ /* { dg-do run { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target ppc_float128_sw } */ -/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-mvsx -O2" } */ #ifdef DEBUG #include <stdio.h> Index: gcc/testsuite/gcc.target/powerpc/float128-mix.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-mix.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-mix.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,7 +1,6 @@ /* { dg-do compile { target { powerpc*-*-linux* } } } */ -/* { dg-require-effective-target powerpc_float128_sw_ok } */ -/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ -/* { dg-options "-O2 -mcpu=power7 -mfloat128" } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ /* Test to make sure that __float128 and long double cannot be combined together. */ Index: gcc/testsuite/gcc.target/powerpc/float128-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-2.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-2.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,6 +1,7 @@ /* { dg-do run { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target ppc_float128_sw } */ -/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-mvsx -O2" } */ /* * Test program to make sure we are getting more precision than the 53 bits we Index: gcc/testsuite/gcc.target/powerpc/float128-3.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-3.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-3.c (.../gcc/testsuite/gcc.target/powerpc) (revision 251130) @@ -0,0 +1,21 @@ +/* { dg-do compile { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx -mno-float128" } */ + +/* Test that we can use #pragma GCC target to enable -mfloat128. */ + +#ifdef __FLOAT128__ +#error "-mno-float128 should disable initially defining __FLOAT128__" +#endif + +#pragma GCC target("float128") + +#ifndef __FLOAT128__ +#error "#pragma GCC target(\"float128\") should enable -mfloat128" +#endif + +__float128 +qadd (__float128 a, __float128 b) +{ + return a+b; +} Index: gcc/testsuite/gcc.target/powerpc/float128-hw.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-hw.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-hw.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,7 +1,6 @@ /* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ /* { dg-require-effective-target powerpc_p9vector_ok } */ -/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-options "-mcpu=power9 -O2 -mfloat128" } */ +/* { dg-options "-mpower9-vector -O2" } */ __float128 f128_add (__float128 a, __float128 b) { return a+b; } __float128 f128_sub (__float128 a, __float128 b) { return a-b; } Index: gcc/testsuite/gcc.target/powerpc/float128-5.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-5.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-5.c (.../gcc/testsuite/gcc.target/powerpc) (revision 251134) @@ -0,0 +1,24 @@ +/* { dg-do compile { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-O2 -mpower9-vector -mno-float128" } */ + +/* Test that we can use #pragma GCC target to enable -mfloat128 and generate + code on ISA 3.0 for the float128 built-in functions. */ + +#ifdef __FLOAT128__ +#error "-mno-float128 should disable initially defining __FLOAT128__" +#endif + +#pragma GCC target("float128") + +#ifndef __FLOAT128__ +#error "#pragma GCC target(\"float128\") should enable -mfloat128" +#endif + +__float128 +qabs (__float128 a) +{ + return __builtin_fabsq (a); +} + +/* { dg-final { scan-assembler "xsabsqp" } } */ Index: gcc/testsuite/gcc.target/powerpc/float128-complex-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-complex-1.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-complex-1.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,7 +1,6 @@ /* { dg-do compile { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target powerpc_float128_sw_ok } */ -/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ -/* { dg-options "-O2 -mcpu=power7 -mfloat128" } */ +/* { dg-options "-O2 -mvsx" } */ #ifndef NO_FLOAT typedef _Complex float float_complex; Index: gcc/testsuite/gcc.target/powerpc/float128-complex-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-complex-2.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-complex-2.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,7 +1,7 @@ /* { dg-do compile { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target powerpc_float128_hw_ok } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-options "-O2 -mcpu=power9 -mfloat128 -mfloat128-hardware" } */ +/* { dg-options "-O2 -mpower9-vector -mfloat128-hardware" } */ #ifndef NO_FLOAT typedef _Complex float float_complex; Index: gcc/testsuite/gcc.target/powerpc/float128-type-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-type-1.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-type-1.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,16 +1,21 @@ /* { dg-do compile { target { powerpc64*-*-linux* && lp64 } } } */ -/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ -/* { dg-options "-mcpu=power8 -O2" } */ +/* { dg-options "-mcpu=power8 -O2 -mno-float128" } */ -/* This test tests whether -mfloat128-type (which enables the underlying IEEE - 128-bit floating point) is enabled by default on VSX Linux 64-bit systems, - even if the keywords __float128 and _Float128 (-mfloat128) are not enabled - via the -mfloat128 switch. Test that power8 generates a call to the +/* This test tests whether the underlying IEEE 128-bit floating point) is + enabled by default on VSX Linux 64-bit systems, even if the keyword + __float128 is not enabled . Test that power8 generates a call to the __addkf3 emulation function. */ +#ifdef __LONG_DOUBLE_IEEE128 +typedef double __attribute__((__mode__(__TF__))) f128_t; +typedef _Complex double __attribute__((__mode__(__TC__))) f128c_t; + +#else typedef double __attribute__((__mode__(__KF__))) f128_t; typedef _Complex double __attribute__((__mode__(__KC__))) f128c_t; +#endif f128_t add_scalar (f128_t a, f128_t b) Index: gcc/testsuite/gcc.target/powerpc/float128-type-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-type-2.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-type-2.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,19 +1,21 @@ /* { dg-do compile { target { powerpc64-*-linux* && lp64 } } } */ /* { dg-require-effective-target powerpc_p9vector_ok } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ -/* { dg-options "-mcpu=power9 -O2" } */ +/* { dg-options "-mcpu=power9 -O2 -mno-float128" } */ -/* This test tests whether -mfloat128-type (which enables the underlying IEEE - 128-bit floating point) is enabled by default on VSX Linux 64-bit systems, - even if the keywords __float128 and _Float128 (-mfloat128) are not enabled - via the -mfloat128 switch. Test that power9 generates the xsaddqp +/* This test tests whether the underlying IEEE 128-bit floating point) is + enabled by default on VSX Linux 64-bit systems, even if the keyword + __float128 is not enabled . Test that power9 generates the xsaddqp instruction. */ -/* The effective target powerpc_float128_hw_ok is not used, as that will pass - -mfloat128. */ +#ifdef __LONG_DOUBLE_IEEE128 +typedef double __attribute__((__mode__(__TF__))) f128_t; +typedef _Complex double __attribute__((__mode__(__TC__))) f128c_t; +#else typedef double __attribute__((__mode__(__KF__))) f128_t; typedef _Complex double __attribute__((__mode__(__KC__))) f128c_t; +#endif f128_t add_scalar (f128_t a, f128_t b) Index: gcc/testsuite/gcc.target/powerpc/float128-cmp.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-cmp.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 251056) +++ gcc/testsuite/gcc.target/powerpc/float128-cmp.c (.../gcc/testsuite/gcc.target/powerpc) (working copy) @@ -1,6 +1,6 @@ /* { dg-do run { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target ppc_float128_sw } */ -/* { dg-options "-mvsx -O2 -mfloat128" } */ +/* { dg-options "-mvsx -O2" } */ #include <stddef.h> #include <stdlib.h> Index: gcc/testsuite/gcc.target/powerpc/float128-4.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-4.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc) (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-4.c (.../gcc/testsuite/gcc.target/powerpc) (revision 251105) @@ -0,0 +1,152 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target ppc_float128_sw } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-mvsx -O2" } */ + +/* This is the same as test float128-1.c, using the _Float128 keyword instead + of __float128, and not using -mfloat128. */ + +#ifdef DEBUG +#include <stdio.h> +#include <stddef.h> +#include <stdint.h> +#include <inttypes.h> +#endif + +#if !defined(__FLOAT128__) || !defined(_ARCH_PPC) +static _Float128 +pass_through (_Float128 x) +{ + return x; +} + +_Float128 (*no_optimize) (_Float128) = pass_through; +#endif + +#ifdef DEBUG +__attribute__((__noinline__)) +static void +print_f128 (_Float128 x) +{ + unsigned sign; + unsigned exponent; + uint64_t mantissa1; + uint64_t mantissa2; + uint64_t upper; + uint64_t lower; + +#if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__) + struct ieee128 { + uint64_t upper; + uint64_t lower; + }; + +#elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__) + struct ieee128 { + uint64_t lower; + uint64_t upper; + }; + +#else +#error "Unknown system" +#endif + + union { + _Float128 f128; + struct ieee128 s128; + } u; + + u.f128 = x; + upper = u.s128.upper; + lower = u.s128.lower; + + sign = (unsigned)((upper >> 63) & 1); + exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1)); + mantissa1 = (upper & ((((uint64_t)1) << 48) - 1)); + mantissa2 = lower; + + printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64, + sign ? '-' : '+', + exponent, + mantissa1, + mantissa2); +} +#endif + +__attribute__((__noinline__)) +static void +do_test (_Float128 expected, _Float128 got, const char *name) +{ + int equal_p = (expected == got); + +#ifdef DEBUG + printf ("Test %s, expected: ", name); + print_f128 (expected); + printf (" %5g, got: ", (double) expected); + print_f128 (got); + printf (" %5g, result %s\n", + (double) got, + (equal_p) ? "equal" : "not equal"); +#endif + + if (!equal_p) + __builtin_abort (); +} + + +int +main (void) +{ + _Float128 one = 1.0f128; + _Float128 two = 2.0f128; + _Float128 three = 3.0f128; + _Float128 four = 4.0f128; + _Float128 five = 5.0f128; + _Float128 add_result = (1.0f128 + 2.0f128); + _Float128 mul_result = ((1.0f128 + 2.0f128) * 3.0f128); + _Float128 div_result = (((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128); + _Float128 sub_result = ((((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128) + - 5.0f128); + _Float128 neg_result = - sub_result; + _Float128 add_xresult; + _Float128 mul_xresult; + _Float128 div_xresult; + _Float128 sub_xresult; + _Float128 neg_xresult; + +#if defined(__FLOAT128__) && defined(_ARCH_PPC) + __asm__ (" #prevent constant folding, %x0" : "+wa" (one)); + __asm__ (" #prevent constant folding, %x0" : "+wa" (two)); + __asm__ (" #prevent constant folding, %x0" : "+wa" (three)); + __asm__ (" #prevent constant folding, %x0" : "+wa" (four)); + __asm__ (" #prevent constant folding, %x0" : "+wa" (five)); + +#else + one = no_optimize (one); + two = no_optimize (two); + three = no_optimize (three); + four = no_optimize (four); + five = no_optimize (five); +#endif + + add_xresult = (one + two); + do_test (add_result, add_xresult, "add"); + + mul_xresult = add_xresult * three; + do_test (mul_result, mul_xresult, "mul"); + + div_xresult = mul_xresult / four; + do_test (div_result, div_xresult, "div"); + + sub_xresult = div_xresult - five; + do_test (sub_result, sub_xresult, "sub"); + + neg_xresult = - sub_xresult; + do_test (neg_result, neg_xresult, "neg"); + +#ifdef DEBUG + printf ("Passed\n"); +#endif + + return 0; +}