Index: gcc/config/rs6000/rs6000-cpus.def =================================================================== --- gcc/config/rs6000/rs6000-cpus.def (revision 251721) +++ gcc/config/rs6000/rs6000-cpus.def (working copy) @@ -86,7 +86,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) #define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC) @@ -112,7 +111,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-c.c =================================================================== --- gcc/config/rs6000/rs6000-c.c (revision 251721) +++ gcc/config/rs6000/rs6000-c.c (working copy) @@ -574,6 +574,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 @@ -601,24 +613,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/config/rs6000/rs6000.opt =================================================================== --- gcc/config/rs6000/rs6000.opt (revision 251721) +++ gcc/config/rs6000/rs6000.opt (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 @@ -562,14 +570,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 (revision 251721) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -4608,73 +4608,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 ("%qs requires VSX support", "-mfloat128"); - 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 ("%qs requires VSX support", "-mfloat128-type"); - - 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 ("%qs requires %qs", "-mfloat128", "-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 ("%qs requires %qs", "-mfloat128-hardware", - "-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; @@ -4696,11 +4665,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); @@ -4767,10 +4731,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)) @@ -16887,16 +16853,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); @@ -16910,24 +16877,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"); } @@ -32558,11 +32511,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 @@ -36041,7 +35997,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 opt_scalar_float_mode (); @@ -36065,7 +36021,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 opt_scalar_float_mode (); @@ -36155,9 +36111,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 (revision 251721) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -639,7 +639,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 @@ -2531,7 +2531,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/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 251721) +++ gcc/doc/invoke.texi (working copy) @@ -22000,15 +22000,21 @@ 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 VSX instruction set (@option{-mvsx}, @option{-mcpu=power7}, +@option{-mcpu=power8}), or @option{-mcpu=power9} 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. + +The default for @option{-mfloat128} is enabled on PowerPC Linux +systems using the VSX instruction set, and disabled on other 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, if you do not specify to +generate ISA 3.0 instructions or you are targeting a 32-bit big endian +system, IEEE 128-bit floating point will be done with software +emulation. @item -mfloat128-hardware @itemx -mno-float128-hardware @@ -22017,12 +22023,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 (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-1.c (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 Index: gcc/testsuite/gcc.target/powerpc/float128-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-2.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-2.c (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-cmp.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-cmp.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-cmp.c (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 #include Index: gcc/testsuite/gcc.target/powerpc/float128-complex-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-complex-1.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-complex-1.c (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 (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-complex-2.c (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-hw.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-hw.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-hw.c (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-mix.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-mix.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-mix.c (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-type-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-type-1.c (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-type-1.c (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 (revision 251721) +++ gcc/testsuite/gcc.target/powerpc/float128-type-2.c (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-3.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-3.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-3.c (revision 0) @@ -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-4.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-4.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-4.c (revision 0) @@ -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 +#include +#include +#include +#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; +} Index: gcc/testsuite/gcc.target/powerpc/float128-5.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/float128-5.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/float128-5.c (revision 0) @@ -0,0 +1,24 @@ +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */ +/* { 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" } } */