+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
| 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
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)
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)
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)
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)
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)
{
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);
}
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
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)
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;
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);
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 ();
}
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)
;; 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"
+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
--- /dev/null
+/* { 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} } } */