rs6000-c.c (is_float128_p): New helper function.
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Tue, 14 Nov 2017 19:53:28 +0000 (19:53 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Tue, 14 Nov 2017 19:53:28 +0000 (19:53 +0000)
[gcc]
2017-11-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

* config/rs6000/rs6000-c.c (is_float128_p): New helper function.
(rs6000_builtin_type_compatible): Treat _Float128 and long double
as being compatible if -mabi=ieeelongdouble.
* config/rs6000/rs6000-builtin.def (BU_FLOAT128_HW_1): New macros
to setup float128 built-ins with hardware support.
(BU_FLOAT128_HW_2): Likewise.
(BU_FLOAT128_HW_3): Likewise.
(BU_FLOAT128_HW_VSX_1): Likewise.
(BU_FLOAT128_HW_VSX_2): Likewise.
(scalar_extract_expq): Change float128 built-in functions to
accommodate having both KFmode and TFmode functions.  Use the
KFmode variant as the default.
(scalar_extract_sigq): Likewise.
(scalar_test_neg_qp): Likewise.
(scalar_insert_exp_q): Likewise.
(scalar_insert_exp_qp): Likewise.
(scalar_test_data_class_qp): Likewise.
(sqrtf128_round_to_odd): Delete processing the round to odd
built-in functions as special built-in functions, and define them
as float128 built-ins.  Use the KFmode variant as the default.
(truncf128_round_to_odd): Likewise.
(addf128_round_to_odd): Likewise.
(subf128_round_to_odd): Likewise.
(mulf128_round_to_odd): Likewise.
(divf128_round_to_odd): Likewise.
(fmaf128_round_to_odd): Likewise.
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
support for KFmode and TFmode xststdcqp calls.
(rs6000_expand_builtin): If long double is IEEE 128-bit floating
point, switch the built-in handlers for the get/set float128
exponent, get float128 mantissa, float128 test built-ins, and the
float128 round to odd built-in functions.  Eliminate creating the
float128 round to odd built-in functions as special built-ins.
(rs6000_init_builtins): Eliminate special creation of the float128
round to odd built-in functions.
* config/rs6000/vsx.md (xsxexpqp_<mode>): Change float128 built-in
function insns to support both TFmode and KFmode variants.
(xsxsigqp_<mode>): Likewise.
(xsiexpqpf_<mode>): Likewise.
(xsiexpqp_<mode>): Likewise.
(xststdcqp_<mode>): Likewise.
(xststdcnegqp_<mode>): Likewise.
(xststdcqp_<mode>): Likewise.

[gcc/testsuite]
2017-11-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

* gcc.target/powerpc/float128-hw4.c: New test.

From-SVN: r254740

gcc/ChangeLog
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000-c.c
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/vsx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/float128-hw4.c [new file with mode: 0644]

index 5870587..0acc100 100644 (file)
@@ -1,3 +1,49 @@
+2017-11-14  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * config/rs6000/rs6000-c.c (is_float128_p): New helper function.
+       (rs6000_builtin_type_compatible): Treat _Float128 and long double
+       as being compatible if -mabi=ieeelongdouble.
+       * config/rs6000/rs6000-builtin.def (BU_FLOAT128_HW_1): New macros
+       to setup float128 built-ins with hardware support.
+       (BU_FLOAT128_HW_2): Likewise.
+       (BU_FLOAT128_HW_3): Likewise.
+       (BU_FLOAT128_HW_VSX_1): Likewise.
+       (BU_FLOAT128_HW_VSX_2): Likewise.
+       (scalar_extract_expq): Change float128 built-in functions to
+       accommodate having both KFmode and TFmode functions.  Use the
+       KFmode variant as the default.
+       (scalar_extract_sigq): Likewise.
+       (scalar_test_neg_qp): Likewise.
+       (scalar_insert_exp_q): Likewise.
+       (scalar_insert_exp_qp): Likewise.
+       (scalar_test_data_class_qp): Likewise.
+       (sqrtf128_round_to_odd): Delete processing the round to odd
+       built-in functions as special built-in functions, and define them
+       as float128 built-ins.  Use the KFmode variant as the default.
+       (truncf128_round_to_odd): Likewise.
+       (addf128_round_to_odd): Likewise.
+       (subf128_round_to_odd): Likewise.
+       (mulf128_round_to_odd): Likewise.
+       (divf128_round_to_odd): Likewise.
+       (fmaf128_round_to_odd): Likewise.
+       * config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
+       support for KFmode and TFmode xststdcqp calls.
+       (rs6000_expand_builtin): If long double is IEEE 128-bit floating
+       point, switch the built-in handlers for the get/set float128
+       exponent, get float128 mantissa, float128 test built-ins, and the
+       float128 round to odd built-in functions.  Eliminate creating the
+       float128 round to odd built-in functions as special built-ins.
+       (rs6000_init_builtins): Eliminate special creation of the float128
+       round to odd built-in functions.
+       * config/rs6000/vsx.md (xsxexpqp_<mode>): Change float128 built-in
+       function insns to support both TFmode and KFmode variants.
+       (xsxsigqp_<mode>): Likewise.
+       (xsiexpqpf_<mode>): Likewise.
+       (xsiexpqp_<mode>): Likewise.
+       (xststdcqp_<mode>): Likewise.
+       (xststdcnegqp_<mode>): Likewise.
+       (xststdcqp_<mode>): Likewise.
+
 2017-11-14  Jan Hubicka  <hubicka@ucw.cz>
 
        * tree-ssa-threadupdate.c (compute_path_counts): Remove
index 1ef98e3..6842c12 100644 (file)
                     | RS6000_BTC_BINARY),                              \
                    CODE_FOR_nothing)                   /* ICODE */
 
+/* Built-in functions for IEEE 128-bit hardware floating point.  IEEE 128-bit
+   hardware requires p9-vector and 64-bit operation.  These functions use just
+   __builtin_ as the prefix.  */
+#define BU_FLOAT128_HW_1(ENUM, NAME, ATTR, ICODE)                      \
+  RS6000_BUILTIN_1 (FLOAT128_BUILTIN_ ## ENUM,         /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_UNARY),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_FLOAT128_HW_2(ENUM, NAME, ATTR, ICODE)                      \
+  RS6000_BUILTIN_2 (FLOAT128_BUILTIN_ ## ENUM,         /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_FLOAT128_HW_3(ENUM, NAME, ATTR, ICODE)                      \
+  RS6000_BUILTIN_3 (FLOAT128_BUILTIN_ ## ENUM,         /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_TERNARY),                             \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+/* Built-in functions for IEEE 128-bit hardware floating point.  These
+   functions use __builtin_vsx_ as the prefix.  */
+#define BU_FLOAT128_HW_VSX_1(ENUM, NAME, ATTR, ICODE)                  \
+  RS6000_BUILTIN_1 (P9V_BUILTIN_ ## ENUM,              /* ENUM */      \
+                   "__builtin_vsx_" NAME,              /* NAME */      \
+                   RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_UNARY),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_FLOAT128_HW_VSX_2(ENUM, NAME, ATTR, ICODE)                  \
+  RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM,              /* ENUM */      \
+                   "__builtin_vsx_" NAME,              /* NAME */      \
+                   RS6000_BTM_FLOAT128_HW,             /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
 #endif
 
 \f
@@ -2064,10 +2109,10 @@ BU_P9V_OVERLOAD_3 (RLMI,        "rlmi")
 BU_P9V_64BIT_VSX_1 (VSEEDP,    "scalar_extract_exp",   CONST,  xsxexpdp)
 BU_P9V_64BIT_VSX_1 (VSESDP,    "scalar_extract_sig",   CONST,  xsxsigdp)
 
-BU_P9V_64BIT_VSX_1 (VSEEQP,    "scalar_extract_expq",  CONST,  xsxexpqp)
-BU_P9V_64BIT_VSX_1 (VSESQP,    "scalar_extract_sigq",  CONST,  xsxsigqp)
+BU_FLOAT128_HW_VSX_1 (VSEEQP,  "scalar_extract_expq",  CONST,  xsxexpqp_kf)
+BU_FLOAT128_HW_VSX_1 (VSESQP,  "scalar_extract_sigq",  CONST,  xsxsigqp_kf)
 
-BU_P9V_VSX_1 (VSTDCNQP,        "scalar_test_neg_qp",   CONST,  xststdcnegqp)
+BU_FLOAT128_HW_VSX_1 (VSTDCNQP, "scalar_test_neg_qp",  CONST,  xststdcnegqp_kf)
 BU_P9V_VSX_1 (VSTDCNDP,        "scalar_test_neg_dp",   CONST,  xststdcnegdp)
 BU_P9V_VSX_1 (VSTDCNSP,        "scalar_test_neg_sp",   CONST,  xststdcnegsp)
 
@@ -2083,15 +2128,15 @@ BU_P9V_VSX_1 (XXBRH_V8HI,       "xxbrh_v8hi",   CONST,  p9_xxbrh_v8hi)
 BU_P9V_64BIT_VSX_2 (VSIEDP,    "scalar_insert_exp",    CONST,  xsiexpdp)
 BU_P9V_64BIT_VSX_2 (VSIEDPF,   "scalar_insert_exp_dp", CONST,  xsiexpdpf)
 
-BU_P9V_64BIT_VSX_2 (VSIEQP,    "scalar_insert_exp_q",  CONST,  xsiexpqp)
-BU_P9V_64BIT_VSX_2 (VSIEQPF,   "scalar_insert_exp_qp", CONST,  xsiexpqpf)
+BU_FLOAT128_HW_VSX_2 (VSIEQP,  "scalar_insert_exp_q",  CONST,  xsiexpqp_kf)
+BU_FLOAT128_HW_VSX_2 (VSIEQPF, "scalar_insert_exp_qp", CONST,  xsiexpqpf_kf)
 
 BU_P9V_VSX_2 (VSCEDPGT,        "scalar_cmp_exp_dp_gt", CONST,  xscmpexpdp_gt)
 BU_P9V_VSX_2 (VSCEDPLT,        "scalar_cmp_exp_dp_lt", CONST,  xscmpexpdp_lt)
 BU_P9V_VSX_2 (VSCEDPEQ,        "scalar_cmp_exp_dp_eq", CONST,  xscmpexpdp_eq)
 BU_P9V_VSX_2 (VSCEDPUO,        "scalar_cmp_exp_dp_unordered",  CONST,  xscmpexpdp_unordered)
 
-BU_P9V_VSX_2 (VSTDCQP, "scalar_test_data_class_qp",    CONST,  xststdcqp)
+BU_FLOAT128_HW_VSX_2 (VSTDCQP, "scalar_test_data_class_qp",    CONST,  xststdcqp_kf)
 BU_P9V_VSX_2 (VSTDCDP, "scalar_test_data_class_dp",    CONST,  xststdcdp)
 BU_P9V_VSX_2 (VSTDCSP, "scalar_test_data_class_sp",    CONST,  xststdcsp)
 
@@ -2173,6 +2218,16 @@ BU_P9V_VSX_2 (VEXTRACT4B,   "vextract4b",        CONST,  vextract4b)
 BU_P9V_VSX_3 (VINSERT4B,    "vinsert4b",       CONST,  vinsert4b)
 BU_P9V_VSX_3 (VINSERT4B_DI, "vinsert4b_di",    CONST,  vinsert4b_di)
 
+/* Hardware IEEE 128-bit floating point round to odd instrucitons added in ISA
+   3.0 (power9).  */
+BU_FLOAT128_HW_1 (SQRTF128_ODD,  "sqrtf128_round_to_odd",  FP, sqrtkf2_odd)
+BU_FLOAT128_HW_1 (TRUNCF128_ODD, "truncf128_round_to_odd", FP, trunckfdf2_odd)
+BU_FLOAT128_HW_2 (ADDF128_ODD,   "addf128_round_to_odd",   FP, addkf3_odd)
+BU_FLOAT128_HW_2 (SUBF128_ODD,   "subf128_round_to_odd",   FP, subkf3_odd)
+BU_FLOAT128_HW_2 (MULF128_ODD,   "mulf128_round_to_odd",   FP, mulkf3_odd)
+BU_FLOAT128_HW_2 (DIVF128_ODD,   "divf128_round_to_odd",   FP, divkf3_odd)
+BU_FLOAT128_HW_3 (FMAF128_ODD,   "fmaf128_round_to_odd",   FP, fmakf4_odd)
+
 /* 3 argument vector functions returning void, treated as SPECIAL,
    added in ISA 3.0 (power9).  */
 BU_P9V_64BIT_AV_X (STXVL,      "stxvl",        MISC)
@@ -2497,34 +2552,6 @@ BU_SPECIAL_X (RS6000_BUILTIN_CPU_IS, "__builtin_cpu_is",
 BU_SPECIAL_X (RS6000_BUILTIN_CPU_SUPPORTS, "__builtin_cpu_supports",
              RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
 
-BU_SPECIAL_X (FLOAT128_BUILTIN_SQRTF128_ODD,
-             "__builtin_sqrtf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_TRUNCF128_ODD,
-             "__builtin_truncf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_ADDF128_ODD,
-             "__builtin_addf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_SUBF128_ODD,
-             "__builtin_subf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_MULF128_ODD,
-             "__builtin_mulf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_DIVF128_ODD,
-             "__builtin_divf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
-BU_SPECIAL_X (FLOAT128_BUILTIN_FMAF128_ODD,
-             "__builtin_fmaf128_round_to_odd",
-             RS6000_BTM_FLOAT128_HW, RS6000_BTC_MISC)
-
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
              RS6000_BTC_MISC)
index c397d20..ef21ba3 100644 (file)
@@ -5759,12 +5759,22 @@ rs6000_builtin_type (int id)
   return id < 0 ? build_pointer_type (t) : t;
 }
 
-/* Check whether the type of an argument, T, is compatible with a
-   type ID stored into a struct altivec_builtin_types.  Integer
-   types are considered compatible; otherwise, the language hook
-   lang_hooks.types_compatible_p makes the decision.  */
+/* Check whether the type of an argument, T, is compatible with a type ID
+   stored into a struct altivec_builtin_types.  Integer types are considered
+   compatible; otherwise, the language hook lang_hooks.types_compatible_p makes
+   the decision.  Also allow long double and _Float128 to be compatible if
+   -mabi=ieeelongdouble.  */
 
 static inline bool
+is_float128_p (tree t)
+{
+  return (t == float128_type_node
+         || (TARGET_IEEEQUAD
+             && TARGET_LONG_DOUBLE_128
+             && t == long_double_type_node));
+}
+  
+static inline bool
 rs6000_builtin_type_compatible (tree t, int id)
 {
   tree builtin_type;
@@ -5773,6 +5783,9 @@ rs6000_builtin_type_compatible (tree t, int id)
     return false;
   if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (builtin_type))
     return true;
+  else if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
+          && is_float128_p (t) && is_float128_p (builtin_type))
+    return true;
   else
     return lang_hooks.types_compatible_p (t, builtin_type);
 }
index 05c0c8b..ab01998 100644 (file)
@@ -14084,7 +14084,8 @@ rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
          return CONST0_RTX (tmode);
        }
     }
-  else if (icode == CODE_FOR_xststdcqp
+  else if (icode == CODE_FOR_xststdcqp_kf
+          || icode == CODE_FOR_xststdcqp_tf
           || icode == CODE_FOR_xststdcdp
           || icode == CODE_FOR_xststdcsp
           || icode == CODE_FOR_xvtstdcdp
@@ -16701,10 +16702,37 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   bool success;
   HOST_WIDE_INT mask = rs6000_builtin_info[uns_fcode].mask;
   bool func_valid_p = ((rs6000_builtin_mask & mask) == mask);
+  enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
+
+  /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit
+     floating point type, depending on whether long double is the IBM extended
+     double (KFmode) or long double is IEEE 128-bit (TFmode).  It is simpler if
+     we only define one variant of the built-in function, and switch the code
+     when defining it, rather than defining two built-ins and using the
+     overload table in rs6000-c.c to switch between the two.  */
+  if (FLOAT128_IEEE_P (TFmode))
+    switch (icode)
+      {
+      default:
+       break;
+
+      case CODE_FOR_sqrtkf2_odd:       icode = CODE_FOR_sqrttf2_odd;   break;
+      case CODE_FOR_trunckfdf2_odd:    icode = CODE_FOR_trunctfdf2_odd; break;
+      case CODE_FOR_addkf3_odd:                icode = CODE_FOR_addtf3_odd;    break;
+      case CODE_FOR_subkf3_odd:                icode = CODE_FOR_subtf3_odd;    break;
+      case CODE_FOR_mulkf3_odd:                icode = CODE_FOR_multf3_odd;    break;
+      case CODE_FOR_divkf3_odd:                icode = CODE_FOR_divtf3_odd;    break;
+      case CODE_FOR_fmakf4_odd:                icode = CODE_FOR_fmatf4_odd;    break;
+      case CODE_FOR_xsxexpqp_kf:       icode = CODE_FOR_xsxexpqp_tf;   break;
+      case CODE_FOR_xsxsigqp_kf:       icode = CODE_FOR_xsxsigqp_tf;   break;
+      case CODE_FOR_xststdcnegqp_kf:   icode = CODE_FOR_xststdcnegqp_tf; break;
+      case CODE_FOR_xsiexpqp_kf:       icode = CODE_FOR_xsiexpqp_tf;   break;
+      case CODE_FOR_xsiexpqpf_kf:      icode = CODE_FOR_xsiexpqpf_tf;  break;
+      case CODE_FOR_xststdcqp_kf:      icode = CODE_FOR_xststdcqp_tf;  break;
+      }
 
   if (TARGET_DEBUG_BUILTIN)
     {
-      enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
       const char *name1 = rs6000_builtin_info[uns_fcode].name;
       const char *name2 = (icode != CODE_FOR_nothing)
                           ? get_insn_name ((int) icode)
@@ -16780,48 +16808,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     case RS6000_BUILTIN_CPU_SUPPORTS:
       return cpu_expand_builtin (fcode, exp, target);
 
-    case FLOAT128_BUILTIN_SQRTF128_ODD:
-      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
-                                        ? CODE_FOR_sqrttf2_odd
-                                        : CODE_FOR_sqrtkf2_odd, exp, target);
-
-    case FLOAT128_BUILTIN_TRUNCF128_ODD:
-      return rs6000_expand_unop_builtin (TARGET_IEEEQUAD
-                                        ? CODE_FOR_trunctfdf2_odd
-                                        : CODE_FOR_trunckfdf2_odd, exp, target);
-
-    case FLOAT128_BUILTIN_ADDF128_ODD:
-      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
-                                         ? CODE_FOR_addtf3_odd
-                                         : CODE_FOR_addkf3_odd, exp, target);
-
-    case FLOAT128_BUILTIN_SUBF128_ODD:
-      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
-                                         ? CODE_FOR_subtf3_odd
-                                         : CODE_FOR_subkf3_odd, exp, target);
-
-    case FLOAT128_BUILTIN_MULF128_ODD:
-      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
-                                         ? CODE_FOR_multf3_odd
-                                         : CODE_FOR_mulkf3_odd, exp, target);
-
-    case FLOAT128_BUILTIN_DIVF128_ODD:
-      return rs6000_expand_binop_builtin (TARGET_IEEEQUAD
-                                         ? CODE_FOR_divtf3_odd
-                                         : CODE_FOR_divkf3_odd, exp, target);
-
-    case FLOAT128_BUILTIN_FMAF128_ODD:
-      return rs6000_expand_ternop_builtin (TARGET_IEEEQUAD
-                                          ? CODE_FOR_fmatf4_odd
-                                          : CODE_FOR_fmakf4_odd, exp, target);
-
     case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
     case ALTIVEC_BUILTIN_MASK_FOR_STORE:
       {
-       int icode = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
+       int icode2 = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
                     : (int) CODE_FOR_altivec_lvsl_direct);
-       machine_mode tmode = insn_data[icode].operand[0].mode;
-       machine_mode mode = insn_data[icode].operand[1].mode;
+       machine_mode tmode = insn_data[icode2].operand[0].mode;
+       machine_mode mode = insn_data[icode2].operand[1].mode;
        tree arg;
        rtx op, addr, pat;
 
@@ -16843,10 +16836,10 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
 
        if (target == 0
            || GET_MODE (target) != tmode
-           || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+           || ! (*insn_data[icode2].operand[0].predicate) (target, tmode))
          target = gen_reg_rtx (tmode);
 
-       pat = GEN_FCN (icode) (target, op);
+       pat = GEN_FCN (icode2) (target, op);
        if (!pat)
          return 0;
        emit_insn (pat);
@@ -16904,25 +16897,25 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   d = bdesc_1arg;
   for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
     if (d->code == fcode)
-      return rs6000_expand_unop_builtin (d->icode, exp, target);
+      return rs6000_expand_unop_builtin (icode, exp, target);
 
   /* Handle simple binary operations.  */
   d = bdesc_2arg;
   for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
     if (d->code == fcode)
-      return rs6000_expand_binop_builtin (d->icode, exp, target);
+      return rs6000_expand_binop_builtin (icode, exp, target);
 
   /* Handle simple ternary operations.  */
   d = bdesc_3arg;
   for (i = 0; i < ARRAY_SIZE  (bdesc_3arg); i++, d++)
     if (d->code == fcode)
-      return rs6000_expand_ternop_builtin (d->icode, exp, target);
+      return rs6000_expand_ternop_builtin (icode, exp, target);
 
   /* Handle simple no-argument operations. */
   d = bdesc_0arg;
   for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
     if (d->code == fcode)
-      return rs6000_expand_zeroop_builtin (d->icode, target);
+      return rs6000_expand_zeroop_builtin (icode, target);
 
   gcc_unreachable ();
 }
@@ -17193,32 +17186,6 @@ rs6000_init_builtins (void)
   def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
   def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
 
-  ftype = build_function_type_list (ieee128_float_type_node,
-                                   ieee128_float_type_node, NULL_TREE);
-  def_builtin ("__builtin_sqrtf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_SQRTF128_ODD);
-  def_builtin ("__builtin_truncf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_TRUNCF128_ODD);
-
-  ftype = build_function_type_list (ieee128_float_type_node,
-                                   ieee128_float_type_node,
-                                   ieee128_float_type_node, NULL_TREE);
-  def_builtin ("__builtin_addf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_ADDF128_ODD);
-  def_builtin ("__builtin_subf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_SUBF128_ODD);
-  def_builtin ("__builtin_mulf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_MULF128_ODD);
-  def_builtin ("__builtin_divf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_DIVF128_ODD);
-
-  ftype = build_function_type_list (ieee128_float_type_node,
-                                   ieee128_float_type_node,
-                                   ieee128_float_type_node,
-                                   ieee128_float_type_node, NULL_TREE);
-  def_builtin ("__builtin_fmaf128_round_to_odd", ftype,
-              FLOAT128_BUILTIN_FMAF128_ODD);
-
   /* AIX libm provides clog as __clog.  */
   if (TARGET_XCOFF &&
       (tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
index 335e5c1..e48d4b3 100644 (file)
 ;; ISA 3.0 Binary Floating-Point Support
 
 ;; VSX Scalar Extract Exponent Quad-Precision
-(define_insn "xsxexpqp"
+(define_insn "xsxexpqp_<mode>"
   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
-       (unspec:DI [(match_operand:KF 1 "altivec_register_operand" "v")]
+       (unspec:DI [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
         UNSPEC_VSX_SXEXPDP))]
   "TARGET_P9_VECTOR"
   "xsxexpqp %0,%1"
   [(set_attr "type" "integer")])
 
 ;; VSX Scalar Extract Significand Quad-Precision
-(define_insn "xsxsigqp"
+(define_insn "xsxsigqp_<mode>"
   [(set (match_operand:TI 0 "altivec_register_operand" "=v")
-       (unspec:TI [(match_operand:KF 1 "altivec_register_operand" "v")]
+       (unspec:TI [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
         UNSPEC_VSX_SXSIG))]
   "TARGET_P9_VECTOR"
   "xsxsigqp %0,%1"
   [(set_attr "type" "integer")])
 
 ;; VSX Scalar Insert Exponent Quad-Precision Floating Point Argument
-(define_insn "xsiexpqpf"
-  [(set (match_operand:KF 0 "altivec_register_operand" "=v")
-       (unspec:KF [(match_operand:KF 1 "altivec_register_operand" "v")
-                   (match_operand:DI 2 "altivec_register_operand" "v")]
+(define_insn "xsiexpqpf_<mode>"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128
+        [(match_operand:IEEE128 1 "altivec_register_operand" "v")
+         (match_operand:DI 2 "altivec_register_operand" "v")]
         UNSPEC_VSX_SIEXPQP))]
   "TARGET_P9_VECTOR"
   "xsiexpqp %0,%1,%2"
   [(set_attr "type" "vecmove")])
 
 ;; VSX Scalar Insert Exponent Quad-Precision
-(define_insn "xsiexpqp"
-  [(set (match_operand:KF 0 "altivec_register_operand" "=v")
-       (unspec:KF [(match_operand:TI 1 "altivec_register_operand" "v")
-                   (match_operand:DI 2 "altivec_register_operand" "v")]
+(define_insn "xsiexpqp_<mode>"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128 [(match_operand:TI 1 "altivec_register_operand" "v")
+                        (match_operand:DI 2 "altivec_register_operand" "v")]
         UNSPEC_VSX_SIEXPQP))]
   "TARGET_P9_VECTOR"
   "xsiexpqp %0,%1,%2"
 ;;   (Has side effect of setting the lt bit if operand 1 is negative,
 ;;    setting the eq bit if any of the conditions tested by operand 2
 ;;    are satisfied, and clearing the gt and undordered bits to zero.)
-(define_expand "xststdcqp"
+(define_expand "xststdcqp_<mode>"
   [(set (match_dup 3)
        (compare:CCFP
-        (unspec:KF
-         [(match_operand:KF 1 "altivec_register_operand" "v")
+        (unspec:IEEE128
+         [(match_operand:IEEE128 1 "altivec_register_operand" "v")
           (match_operand:SI 2 "u7bit_cint_operand" "n")]
          UNSPEC_VSX_STSTDC)
         (const_int 0)))
 })
 
 ;; The VSX Scalar Test Negative Quad-Precision
-(define_expand "xststdcnegqp"
+(define_expand "xststdcnegqp_<mode>"
   [(set (match_dup 2)
        (compare:CCFP
-        (unspec:KF
-         [(match_operand:KF 1 "altivec_register_operand" "v")
+        (unspec:IEEE128
+         [(match_operand:IEEE128 1 "altivec_register_operand" "v")
           (const_int 0)]
          UNSPEC_VSX_STSTDC)
         (const_int 0)))
   operands[3] = CONST0_RTX (SImode);
 })
 
-(define_insn "*xststdcqp"
+(define_insn "*xststdcqp_<mode>"
   [(set (match_operand:CCFP 0 "" "=y")
        (compare:CCFP
-        (unspec:KF [(match_operand:KF 1 "altivec_register_operand" "v")
-                    (match_operand:SI 2 "u7bit_cint_operand" "n")]
+        (unspec:IEEE128
+         [(match_operand:IEEE128 1 "altivec_register_operand" "v")
+          (match_operand:SI 2 "u7bit_cint_operand" "n")]
          UNSPEC_VSX_STSTDC)
         (const_int 0)))]
   "TARGET_P9_VECTOR"
index 16836fa..ec43496 100644 (file)
@@ -1,3 +1,7 @@
+2017-11-14  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/float128-hw4.c: New test.
+
 2017-11-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * lib/target-supports.exp (check_effective_target_pie): Adapt
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw4.c b/gcc/testsuite/gcc.target/powerpc/float128-hw4.c
new file mode 100644 (file)
index 0000000..be5d0d6
--- /dev/null
@@ -0,0 +1,135 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -mabi=ieeelongdouble -Wno-psabi" } */
+
+/* Insure that the ISA 3.0 IEEE 128-bit floating point built-in functions can
+   be used with long double when the default is IEEE 128-bit.  */
+
+#ifndef TYPE
+#define TYPE long double
+#endif
+
+unsigned int
+get_double_exponent (double a)
+{
+  return __builtin_vec_scalar_extract_exp (a);
+}
+
+unsigned int
+get_float128_exponent (TYPE a)
+{
+  return __builtin_vec_scalar_extract_exp (a);
+}
+
+unsigned long
+get_double_mantissa (double a)
+{
+  return __builtin_vec_scalar_extract_sig (a);
+}
+
+__uint128_t
+get_float128_mantissa (TYPE a)
+{
+  return __builtin_vec_scalar_extract_sig (a);
+}
+
+double
+set_double_exponent_ulong (unsigned long a, unsigned long e)
+{
+  return __builtin_vec_scalar_insert_exp (a, e);
+}
+
+TYPE
+set_float128_exponent_uint128 (__uint128_t a, unsigned long e)
+{
+  return __builtin_vec_scalar_insert_exp (a, e);
+}
+
+double
+set_double_exponent_double (double a, unsigned long e)
+{
+  return __builtin_vec_scalar_insert_exp (a, e);
+}
+
+TYPE
+set_float128_exponent_float128 (TYPE a, __uint128_t e)
+{
+  return __builtin_vec_scalar_insert_exp (a, e);
+}
+
+TYPE
+sqrt_odd (TYPE a)
+{
+  return __builtin_sqrtf128_round_to_odd (a);
+}
+
+double
+trunc_odd (TYPE a)
+{
+  return __builtin_truncf128_round_to_odd (a);
+}
+
+TYPE
+add_odd (TYPE a, TYPE b)
+{
+  return __builtin_addf128_round_to_odd (a, b);
+}
+
+TYPE
+sub_odd (TYPE a, TYPE b)
+{
+  return __builtin_subf128_round_to_odd (a, b);
+}
+
+TYPE
+mul_odd (TYPE a, TYPE b)
+{
+  return __builtin_mulf128_round_to_odd (a, b);
+}
+
+TYPE
+div_odd (TYPE a, TYPE b)
+{
+  return __builtin_divf128_round_to_odd (a, b);
+}
+
+TYPE
+fma_odd (TYPE a, TYPE b, TYPE c)
+{
+  return __builtin_fmaf128_round_to_odd (a, b, c);
+}
+
+TYPE
+fms_odd (TYPE a, TYPE b, TYPE c)
+{
+  return __builtin_fmaf128_round_to_odd (a, b, -c);
+}
+
+TYPE
+nfma_odd (TYPE a, TYPE b, TYPE c)
+{
+  return -__builtin_fmaf128_round_to_odd (a, b, c);
+}
+
+TYPE
+nfms_odd (TYPE a, TYPE b, TYPE c)
+{
+  return -__builtin_fmaf128_round_to_odd (a, b, -c);
+}
+
+/* { dg-final { scan-assembler            {\mxsiexpdp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsiexpqp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsxexpdp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsxexpqp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsxsigdp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsxsigqp\M}   } } */
+/* { dg-final { scan-assembler            {\mxsaddqpo\M}   } } */
+/* { dg-final { scan-assembler            {\mxsdivqpo\M}   } } */
+/* { dg-final { scan-assembler            {\mxsmaddqpo\M}  } } */
+/* { dg-final { scan-assembler            {\mxsmsubqpo\M}  } } */
+/* { dg-final { scan-assembler            {\mxsmulqpo\M}   } } */
+/* { dg-final { scan-assembler            {\mxsnmaddqpo\M} } } */
+/* { dg-final { scan-assembler            {\mxsnmsubqpo\M} } } */
+/* { dg-final { scan-assembler            {\mxssqrtqpo\M}  } } */
+/* { dg-final { scan-assembler            {\mxssubqpo\M}   } } */
+/* { dg-final { scan-assembler-not {\mbl\M}         } } */