+2017-09-07 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-cpus.def (OTHER_VSX_VECTOR_MASKS): Delete
+ OPTION_MASK_FLOAT128_KEYWORD.
+ (POWERPC_MASKS): Likewise.
+ * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Delete
+ support for the -mfloat128-type option, and make -mfloat128
+ default on PowerPC Linux systems. Define or undefine
+ __FLOAT128__ and __FLOAT128_HARDWARE__ for the current options.
+ Define __float128 to be __ieee128 if IEEE 128-bit support is
+ enabled, or undefine it.
+ (rs6000_cpu_cpp_builtins): Delete defining __FLOAT128__ here.
+ Delete defining __FLOAT128_TYPE__.
+ * config/rs6000/rs6000.opt (x_TARGET_FLOAT128_TYPE): Delete the
+ -mfloat128-type option and make -mfloat128 default on PowerPC
+ Linux systems.
+ (TARGET_FLOAT128_TYPE): Likewise.
+ (-mfloat128-type): Likewise.
+ * config/rs6000/rs6000.c (rs6000_option_override_internal):
+ Delete the -mfloat128-type option and make -mfloat128 default on
+ PowerPC Linux systems. Always use __ieee128 to be the keyword for
+ the IEEE 128-bit type, and map __float128 to __ieee128 if IEEE
+ 128-bit floating point is enabled. Change tests from using
+ -mfloat128-type to -mfloat128.
+ (rs6000_mangle_type): Use the correct mangling for the __float128
+ type even if normal long double is restricted to 64-bits.
+ (floatn_mode): Enable the _Float128 type by default on VSX Linux
+ systems.
+ * config/rs6000/rs6000.h (MASK_FLOAT128_TYPE): Delete.
+ (MASK_FLOAT128_KEYWORD): Define new shortcut macro.
+ (RS6000BTM_FLOAT128): Define in terms of -mfloat128, not
+ -mfloat128-type.
+ * doc/invoke.texi (RS/6000 and PowerPC Options): Update
+ documentation for -mfloat128.
+
2017-09-06 Olivier Hainque <hainque@adacore.com>
* config.gcc (powerpc-wrs-vxworksspe): Now match as vxworks*spe.
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
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. */
#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)
| 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 \
#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;
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);
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))
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);
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");
}
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
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 ();
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 ();
{ "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 },
#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
#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 \
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
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.
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
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
+2017-09-07 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/float128-1.c: Update options to know that
+ -mfloat128 is now on by default on PowerPC VSX systems. Remove
+ -static-libgcc option which is no longer needed. Use -mvsx or
+ -mpower9-vector to enable VSX or hardware IEEE support, rather
+ than specifying a particular CPU.
+ * 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.
+ * gcc.target/powerpc/float128-3.c: New test.
+ * gcc.target/powerpc/float128-4.c: Likewise.
+ * gcc.target/powerpc/float128-5.c: Likewise.
+
2017-09-06 Wilco Dijkstra <wdijkstr@arm.com>
PR middle-end/78468
/* { 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>
/* { 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
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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" } } */
/* { 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>
/* { 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;
/* { 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;
/* { 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; }
/* { 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. */
/* { 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)
/* { 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)