PR61415 shows a problem for two test cases that should only be tested if the
target supports a 128-bit long double.  In addition, the 128-bit long double
pack and unpack builtins should not be enabled unless the target supports
128-bit long double.  The following patch accomplishes that, as well as
removing the unused (and redundant) builtins __builtin_longdouble_dw0 and
__builtin_longdouble_dw1.

Is this ok for trunk assuming my powerpc64le-linux bootstrap and regtesting
are clean?

Is this also ok for the FSF 4.9 and FSF 4.8 branches?  Without the gcc/
changes, we hit an ICE whenever we call __builtin_pack_longdouble and
__builtin_unpack_longdouble when -mlong-double-64 is in effect.

Peter


gcc/
        PR target/61415
        * config/rs6000/rs6000-builtin.def (BU_MISC_1): Delete.
        (BU_MISC_2): Rename to ...
        (BU_LDBL128_2): ... this.
        * config/rs6000/rs6000.h (RS6000_BTM_LDBL128): New define.
        (RS6000_BTM_COMMON): Add RS6000_BTM_LDBL128.
        * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Handle
        RS6000_BTM_LDBL128.
        (rs6000_invalid_builtin): Add long double 128-bit builtin support.
        (rs6000_builtin_mask_names): Add RS6000_BTM_LDBL128.
        * config/rs6000/rs6000.md (unpacktf_0): Remove define)expand.
        (unpacktf_1): Likewise.
        * doc/extend.texi (__builtin_longdouble_dw0): Remove documentation.
        (__builtin_longdouble_dw1): Likewise.
        * doc/sourcebuild.texi (longdouble128): Document.

gcc/testsuite/
        PR target/61415
        * lib/target-supports.exp (check_effective_target_longdouble128): New.
        * gcc.target/powerpc/pack02.c: Use it.
        * gcc.target/powerpc/tfmode_off.c: Likewise.

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def        (revision 211281)
+++ gcc/config/rs6000/rs6000-builtin.def        (working copy)
@@ -622,20 +622,13 @@
                     | RS6000_BTC_TERNARY),                             \
                    CODE_FOR_ ## ICODE)                 /* ICODE */
 
-/* Miscellaneous builtins.  */
-#define BU_MISC_1(ENUM, NAME, ATTR, ICODE)                             \
+/* 128-bit long double floating point builtins.  */
+#define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE)                          \
   RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
                    "__builtin_" NAME,                  /* NAME */      \
-                   RS6000_BTM_HARD_FLOAT,              /* MASK */      \
+                   (RS6000_BTM_HARD_FLOAT              /* MASK */      \
+                    | RS6000_BTM_LDBL128),                             \
                    (RS6000_BTC_ ## ATTR                /* ATTR */      \
-                    | RS6000_BTC_UNARY),                               \
-                   CODE_FOR_ ## ICODE)                 /* ICODE */
-
-#define BU_MISC_2(ENUM, NAME, ATTR, ICODE)                             \
-  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
-                   "__builtin_" NAME,                  /* NAME */      \
-                   RS6000_BTM_HARD_FLOAT,              /* MASK */      \
-                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
                     | RS6000_BTC_BINARY),                              \
                    CODE_FOR_ ## ICODE)                 /* ICODE */
 
@@ -1593,10 +1586,8 @@
 BU_DFP_MISC_2 (PACK_TD,                "pack_dec128",          CONST,  packtd)
 BU_DFP_MISC_2 (UNPACK_TD,      "unpack_dec128",        CONST,  unpacktd)
 
-BU_MISC_2 (PACK_TF,            "pack_longdouble",      CONST,  packtf)
-BU_MISC_2 (UNPACK_TF,          "unpack_longdouble",    CONST,  unpacktf)
-BU_MISC_1 (UNPACK_TF_0,                "longdouble_dw0",       CONST,  
unpacktf_0)
-BU_MISC_1 (UNPACK_TF_1,                "longdouble_dw1",       CONST,  
unpacktf_1)
+BU_LDBL128_2 (PACK_TF,         "pack_longdouble",      CONST,  packtf)
+BU_LDBL128_2 (UNPACK_TF,       "unpack_longdouble",    CONST,  unpacktf)
 
 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 211281)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -3041,7 +3041,8 @@
          | ((TARGET_CRYPTO)                ? RS6000_BTM_CRYPTO    : 0)
          | ((TARGET_HTM)                   ? RS6000_BTM_HTM       : 0)
          | ((TARGET_DFP)                   ? RS6000_BTM_DFP       : 0)
-         | ((TARGET_HARD_FLOAT)            ? RS6000_BTM_HARD_FLOAT : 0));
+         | ((TARGET_HARD_FLOAT)            ? RS6000_BTM_HARD_FLOAT : 0)
+         | ((TARGET_LONG_DOUBLE_128)       ? RS6000_BTM_LDBL128 : 0));
 }
 
 /* Override command line options.  Mostly we process the processor type and
@@ -13559,11 +13560,15 @@
   else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
           == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
     error ("Builtin function %s requires the -mhard-dfp and"
-          "-mpower8-vector options", name);
+          " -mpower8-vector options", name);
   else if ((fnmask & RS6000_BTM_DFP) != 0)
     error ("Builtin function %s requires the -mhard-dfp option", name);
   else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
     error ("Builtin function %s requires the -mpower8-vector option", name);
+  else if ((fnmask & (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
+          == (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128))
+    error ("Builtin function %s requires the -mhard-float and"
+          " -mlong-double-128 options", name);
   else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
     error ("Builtin function %s requires the -mhard-float option", name);
   else
@@ -31383,6 +31388,7 @@
   { "htm",              RS6000_BTM_HTM,        false, false },
   { "hard-dfp",                 RS6000_BTM_DFP,        false, false },
   { "hard-float",       RS6000_BTM_HARD_FLOAT, false, false },
+  { "long-double-128",  RS6000_BTM_LDBL128,    false, false },
 };
 
 /* Option variables that we want to support inside attribute((target)) and
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h  (revision 211281)
+++ gcc/config/rs6000/rs6000.h  (working copy)
@@ -2501,8 +2501,8 @@
 #define RS6000_BTC_SAT         RS6000_BTC_MISC /* saturate sets VSCR.  */
 
 /* Builtin targets.  For now, we reuse the masks for those options that are in
-   target flags, and pick two random bits for SPE and paired which aren't in
-   target_flags.  */
+   target flags, and pick three random bits for SPE, paired and ldbl128 which
+   aren't in target_flags.  */
 #define RS6000_BTM_ALWAYS      0               /* Always enabled.  */
 #define RS6000_BTM_ALTIVEC     MASK_ALTIVEC    /* VMX/altivec vectors.  */
 #define RS6000_BTM_VSX         MASK_VSX        /* VSX (vector/scalar).  */
@@ -2519,6 +2519,7 @@
 #define RS6000_BTM_CELL                MASK_FPRND      /* Target is cell 
powerpc.  */
 #define RS6000_BTM_DFP         MASK_DFP        /* Decimal floating point.  */
 #define RS6000_BTM_HARD_FLOAT  MASK_SOFT_FLOAT /* Hardware floating point.  */
+#define RS6000_BTM_LDBL128     MASK_MULTIPLE   /* 128-bit long double.  */
 
 #define RS6000_BTM_COMMON      (RS6000_BTM_ALTIVEC                     \
                                 | RS6000_BTM_VSX                       \
@@ -2532,7 +2533,8 @@
                                 | RS6000_BTM_POPCNTD                   \
                                 | RS6000_BTM_CELL                      \
                                 | RS6000_BTM_DFP                       \
-                                | RS6000_BTM_HARD_FLOAT)
+                                | RS6000_BTM_HARD_FLOAT                \
+                                | RS6000_BTM_LDBL128)
 
 /* Define builtin enum index.  */
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 211281)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -15704,26 +15704,6 @@
   ""
   "")
 
-;; The Advance Toolchain 7.0-3 added private builtins: __builtin_longdouble_dw0
-;; and __builtin_longdouble_dw1 to optimize glibc.  Add support for these
-;; builtins here.
-
-(define_expand "unpacktf_0"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "")
-       (unspec:DF [(match_operand:TF 1 "register_operand" "")
-                   (const_int 0)]
-        UNSPEC_UNPACK_128BIT))]
-  ""
-  "")
-
-(define_expand "unpacktf_1"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "")
-       (unspec:DF [(match_operand:TF 1 "register_operand" "")
-                   (const_int 1)]
-        UNSPEC_UNPACK_128BIT))]
-  ""
-  "")
-
 (define_insn_and_split "unpack<mode>_dm"
   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
        (unspec:<FP128_64>
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 211281)
+++ gcc/doc/extend.texi (working copy)
@@ -13411,8 +13411,6 @@
 uint64_t __builtin_ppc_get_timebase ();
 unsigned long __builtin_ppc_mftb ();
 double __builtin_unpack_longdouble (long double, int);
-double __builtin_longdouble_dw0 (long double);
-double __builtin_longdouble_dw1 (long double);
 long double __builtin_pack_longdouble (double, double);
 @end smallexample
 
Index: gcc/testsuite/gcc.target/powerpc/pack02.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pack02.c   (revision 211281)
+++ gcc/testsuite/gcc.target/powerpc/pack02.c   (working copy)
@@ -2,6 +2,7 @@
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
 /* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
 /* { dg-require-effective-target powerpc_fprs } */
+/* { dg-require-effective-target longdouble128 } */
 /* { dg-options "-O2 -mhard-float" } */
 
 #include <stddef.h>
Index: gcc/testsuite/gcc.target/powerpc/tfmode_off.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/tfmode_off.c       (revision 211281)
+++ gcc/testsuite/gcc.target/powerpc/tfmode_off.c       (working copy)
@@ -1,6 +1,7 @@
 /* { dg-do assemble } */
 /* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
 /* { dg-skip-if "no TFmode" { powerpc-*-eabi* } { "*" } { "" } } */
+/* { dg-require-effective-target longdouble128 } */
 /* { dg-options "-O2 -fno-align-functions -mtraceback=no -save-temps" } */
 
 typedef float TFmode __attribute__ ((mode (TF)));
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp       (revision 211281)
+++ gcc/testsuite/lib/target-supports.exp       (working copy)
@@ -1862,6 +1862,15 @@
     }]
 }
 
+# Return 1 if the target supports long double of 128 bits,
+# 0 otherwise.
+
+proc check_effective_target_longdouble128 { } {
+    return [check_no_compiler_messages longdouble128 object {
+       int dummy[sizeof(long double) == 16 ? 1 : -1];
+    }]
+}
+
 # Return 1 if the target supports double of 64 bits,
 # 0 otherwise.
 
Index: gcc/doc/sourcebuild.texi
===================================================================
--- gcc/doc/sourcebuild.texi    (revision 211281)
+++ gcc/doc/sourcebuild.texi    (working copy)
@@ -1295,6 +1295,9 @@
 @item double64plus
 Target has @code{double} that is 64 bits or longer.
 
+@item longdouble128
+Target has 128-bit @code{long double}.
+
 @item int32plus
 Target has @code{int} that is at 32 bits or longer.
 


Reply via email to