This is the final patch (at least so far) that turns on -mfloat128 by default
for PowerPC Linux systems where the VSX instruction set is enabled. As I
mentioned in the last email, because we don't build the __float128 emulator on
other systems, I didn't think it would be useful to make it the default.
I did a boostrap build/check with no regressions on a little endian power8
system. Are the patches ok to check in?
[gcc]
2016-01-21 Michael Meissner
* config/rs6000/rs6000.c (rs6000_option_override_internal): Enable
-mfloat128 by default on PowerPC Linux systems with the VSX
instruction enabled.
[gcc/testsuite]
2016-01-21 Michael Meissner
* gcc.target/powerpc/float128-1.c: New test for IEEE 128-bit
floating point support.
* gcc.target/powerpc/float128-2.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.c
===
--- gcc/config/rs6000/rs6000.c (revision 232690)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -4236,6 +4236,15 @@ rs6000_option_override_internal (bool gl
}
}
+ /* At present, we only build the __float128 emulator on PowerPC Linux.
+ Enable default __float128 support for PowerPC Linux systems, but not for
+ others. */
+#ifdef POWERPC_LINUX
+ if (TARGET_VSX && !TARGET_FLOAT128
+ && (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) == 0)
+rs6000_isa_flags |= OPTION_MASK_FLOAT128;
+#endif
+
/* __float128 requires VSX support. */
if (TARGET_FLOAT128 && !TARGET_VSX)
{
Index: gcc/testsuite/gcc.target/powerpc/float128-1.c
===
--- gcc/testsuite/gcc.target/powerpc/float128-1.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-1.c (revision 0)
@@ -0,0 +1,147 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */
+
+#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.0q;
+ __float128 two = 2.0q;
+ __float128 three = 3.0q;
+ __float128 four = 4.0q;
+ __float128 five = 5.0q;
+ __float128 add_result = (1.0q + 2.0q);
+ __float128 mul_result = ((1.0q + 2.0q) * 3.0q);
+ __float128 div_result = (((1.0q + 2.0q) * 3.0q) / 4.0q);
+ __float128 sub_result = 1.0q + 2.0q) * 3.0q) / 4.0q) - 5.0q);
+ __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