This patch makes the long double pack/unpack built-in functions only available
if the long double format is IBM extended double.

I added new pack and unpack functions that use __ibm128 instead of long double
in case somebody needs to build IBM extended double after we have changed the
default to IEEE 128-bit.

I have checked this on a little endian power8 Linux system, and there were no
regressions.  All three of the new tests pass.  Can I check this into the
trunk, and eventually back port it to the GCC 8.2 branch?

[gcc]
2018-06-05  Michael Meissner  <meiss...@linux.ibm.com>

        PR target/85657
        * config/rs6000/rs6000-builtin.def (BU_IBM128_2): New helper
        macro for __ibm128 built-in functions.
        (PACK_IF): Add __ibm128 pack/unpack functions.
        (UNPACK_IF): Likewise.
        * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Do not
        enable long double built-in functions if long double is IEEE
        128-bit floating point.
        (rs6000_invalid_builtin): Update long double built-in function
        error message.
        (rs6000_expand_builtin): For PACK_IF and UNPACK_IF built-in
        functions, adjust the built-in function to use the long double
        built-in function if __ibm128 and long double are the same type.
        * doc/extend.texi (PowerPC builtins): Update documention for
        __builtin_{,un}pack_longdouble.  Add documentation for
        __builtin_{,un}pack_ibm128.

[gcc/testsuite]
2018-06-05  Michael Meissner  <meiss...@linux.ibm.com>

        PR target/85657
        * gcc.target/powerpc/pr85657-4.c: New tests.
        * gcc.target/powerpc/pr85657-5.c: Likewise.
        * gcc.target/powerpc/pr85657-6.c: Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def        (revision 261170)
+++ gcc/config/rs6000/rs6000-builtin.def        (working copy)
@@ -628,6 +628,17 @@
                     | RS6000_BTC_BINARY),                              \
                    CODE_FOR_ ## ICODE)                 /* ICODE */
 
+/* 128-bit __ibm128 floating point builtins (use -mfloat128 to indicate that
+   __ibm128 is available).  */
+#define BU_IBM128_2(ENUM, NAME, ATTR, ICODE)                           \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   (RS6000_BTM_HARD_FLOAT              /* MASK */      \
+                    | RS6000_BTM_FLOAT128),                            \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
 /* Miscellaneous builtins for instructions added in ISA 3.0.  These
    instructions don't require either the DFP or VSX options, just the basic
    ISA 3.0 enablement since they operate on general purpose registers.  */
@@ -2315,6 +2326,9 @@ BU_P9_64BIT_MISC_0 (DARN, "darn",                 MISC
 BU_LDBL128_2 (PACK_TF,         "pack_longdouble",      CONST,  packtf)
 BU_LDBL128_2 (UNPACK_TF,       "unpack_longdouble",    CONST,  unpacktf)
 
+BU_IBM128_2 (PACK_IF,          "pack_ibm128",          CONST,  packif)
+BU_IBM128_2 (UNPACK_IF,                "unpack_ibm128",        CONST,  
unpackif)
+
 BU_P7_MISC_2 (PACK_V1TI,       "pack_vector_int128",   CONST,  packv1ti)
 BU_P7_MISC_2 (UNPACK_V1TI,     "unpack_vector_int128", CONST,  unpackv1ti)
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 261209)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -3907,7 +3907,8 @@ rs6000_builtin_mask_calculate (void)
          | ((TARGET_HTM)                   ? RS6000_BTM_HTM       : 0)
          | ((TARGET_DFP)                   ? RS6000_BTM_DFP       : 0)
          | ((TARGET_HARD_FLOAT)            ? RS6000_BTM_HARD_FLOAT : 0)
-         | ((TARGET_LONG_DOUBLE_128)       ? RS6000_BTM_LDBL128   : 0)
+         | ((TARGET_LONG_DOUBLE_128
+             && !TARGET_IEEEQUAD)          ? RS6000_BTM_LDBL128   : 0)
          | ((TARGET_FLOAT128_TYPE)         ? RS6000_BTM_FLOAT128  : 0)
          | ((TARGET_FLOAT128_HW)           ? RS6000_BTM_FLOAT128_HW : 0));
 }
@@ -15339,10 +15340,9 @@ rs6000_invalid_builtin (enum rs6000_buil
   else if ((fnmask & RS6000_BTM_P9_MISC) == RS6000_BTM_P9_MISC)
     error ("builtin function %qs requires the %qs option", name,
           "-mcpu=power9");
-  else if ((fnmask & (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
-          == (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
-    error ("builtin function %qs requires the %qs and %qs options",
-          name, "-mhard-float", "-mlong-double-128");
+  else if ((fnmask & RS6000_BTM_LDBL128) == RS6000_BTM_LDBL128)
+    error ("builtin function %qs requires the %qs option", name,
+          TARGET_IEEEQUAD ? "-mabi=ibmlongdouble" : "-mlong-double-128");
   else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
     error ("builtin function %qs requires the %qs option", name,
           "-mhard-float");
@@ -16213,6 +16213,26 @@ rs6000_expand_builtin (tree exp, rtx tar
        }
       break;
 
+      /* For the pack and unpack int128 routines, fix up the builtin so it
+        uses the correct IBM128 type.  */
+    case MISC_BUILTIN_PACK_IF:
+      if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
+       {
+         icode = CODE_FOR_packtf;
+         fcode = MISC_BUILTIN_PACK_TF;
+         uns_fcode = (size_t)fcode;
+       }
+      break;
+
+    case MISC_BUILTIN_UNPACK_IF:
+      if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
+       {
+         icode = CODE_FOR_unpacktf;
+         fcode = MISC_BUILTIN_UNPACK_TF;
+         uns_fcode = (size_t)fcode;
+       }
+      break;
+
     default:
       break;
     }
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 261170)
+++ gcc/doc/extend.texi (working copy)
@@ -15790,6 +15790,8 @@ processors:
 @smallexample
 uint64_t __builtin_ppc_get_timebase ();
 unsigned long __builtin_ppc_mftb ();
+__ibm128 __builtin_unpack_ibm128 (__ibm128, int);
+__ibm128 __builtin_pack_ibm128 (double, double);
 @end smallexample
 
 The @code{__builtin_ppc_get_timebase} and @code{__builtin_ppc_mftb}
@@ -15872,10 +15874,32 @@ the reciprocal estimate instructions.
 The following functions require @option{-mhard-float} and
 @option{-mmultiple} options.
 
-@smallexample
-long double __builtin_pack_longdouble (double, double);
-double __builtin_unpack_longdouble (long double, int);
-@end smallexample
+The @code{__builtin_unpack_longdouble} function takes a
+@code{long double} argument and a compile time constant of 0 or 1.  If
+the constant is 0, the first @code{double} within the
+@code{long double} is returned, otherwise the second @code{double}
+is returned.  The @code{__builtin_unpack_longdouble} function is only
+availble if @code{long double} uses the IBM extended double
+representation.
+
+The @code{__builtin_pack_longdouble} function takes two @code{double}
+arguments and returns a @code{long double} value that combines the two
+arguments.  The @code{__builtin_pack_longdouble} function is only
+availble if @code{long double} uses the IBM extended double
+representation.
+
+The @code{__builtin_unpack_ibm128} function takes a @code{__ibm128}
+argument and a compile time constant of 0 or 1.  If the constant is 0,
+the first @code{double} within the @code{__ibm128} is returned,
+otherwise the second @code{double} is returned.
+
+The @code{__builtin_pack_ibm128} function takes two @code{double}
+arguments and returns a @code{__ibm128} value that combines the two
+arguments.
+
+Additional built-in functions are available for the 64-bit PowerPC
+family of processors, for efficient use of 128-bit floating point
+(@code{__float128}) values.
 
 @node Basic PowerPC Built-in Functions Available on ISA 2.06
 @subsubsection Basic PowerPC Built-in Functions Available on ISA 2.06
Index: gcc/testsuite/gcc.target/powerpc/pr85657-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr85657-4.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr85657-4.c        (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-mvsx -mfloat128 -O2" } */
+
+/* PR 85657 -- test __builtin_pack_ibm128.  */
+
+__ibm128
+pack (double dummy, double a, double b)
+{
+  /* Should just generate some moves.  */
+  return __builtin_pack_ibm128 (a, b);
+}
+
+/* { dg-final { scan-assembler     {\m(fmr|xxlor)\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
+/* { dg-final { scan-assembler-not {\m(stfd|stxsd)x?\M} } } */
+/* { dg-final { scan-assembler-not {\m(lfd|lxsd)x?\M} } } */
+/* { dg-final { scan-assembler-not {\m(mtvsrd|mfvsrd)\M} } } */
Index: gcc/testsuite/gcc.target/powerpc/pr85657-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr85657-5.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr85657-5.c        (working copy)
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-mvsx -mfloat128 -O2" } */
+
+/* PR 85657 -- test __builtin_unpack_ibm128.  Each call should generate just 1
+   move.  */
+
+double
+unpack0 (double dummy, __ibm128 x)
+{
+  return __builtin_unpack_ibm128 (x, 0);
+}
+
+double
+unpack1 (double dummy, __ibm128 x)
+{
+  /* Should just generate some moves.  */
+  return __builtin_unpack_ibm128 (x, 1);
+}
+
+/* { dg-final { scan-assembler     {\m(fmr|xxlor)\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
+/* { dg-final { scan-assembler-not {\m(stfd|stxsd)x?\M} } } */
+/* { dg-final { scan-assembler-not {\m(lfd|lxsd)x?\M} } } */
+/* { dg-final { scan-assembler-not {\m(mtvsrd|mfvsrd)\M} } } */
Index: gcc/testsuite/gcc.target/powerpc/pr85657-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr85657-6.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr85657-6.c        (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-mvsx -mfloat128 -O2 -mabi=ieeelongdouble -Wno-psabi" } */
+
+/* PR 85657 -- test that __builtin_pack_longdouble and
+   __builtin_unpack_longdouble get the appropriate error messages.  */
+
+long double
+pack (double a, double b)
+{
+  return __builtin_pack_longdouble (a, b); /* { dg-error "builtin function 
'__builtin_pack_longdouble'" } */
+}
+
+double
+unpack0 (long double x)
+{
+  return __builtin_unpack_longdouble (x, 0); /* { dg-error "builtin function 
'__builtin_unpack_longdouble'" } */
+}

Reply via email to