Re: [PATCH], PowerPC IEEE 128-bit fp, #12 (default -mfloat128 on PowerPC-Linux)

2016-01-26 Thread David Edelsohn
On Thu, Jan 21, 2016 at 4:25 PM, Michael Meissner
 wrote:
> 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.

No.  This is too risky a change during Stage 4.

- David


Re: [PATCH], PowerPC IEEE 128-bit fp, #12 (default -mfloat128 on PowerPC-Linux)

2016-01-21 Thread Michael Meissner
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