From cdb4b7aa2f7a6e3b437c0d99e23f8e402b8eeb7d Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 14 Nov 2017 19:53:28 +0000 Subject: [PATCH] rs6000-c.c (is_float128_p): New helper function. [gcc] 2017-11-14 Michael Meissner * 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_): Change float128 built-in function insns to support both TFmode and KFmode variants. (xsxsigqp_): Likewise. (xsiexpqpf_): Likewise. (xsiexpqp_): Likewise. (xststdcqp_): Likewise. (xststdcnegqp_): Likewise. (xststdcqp_): Likewise. [gcc/testsuite] 2017-11-14 Michael Meissner * gcc.target/powerpc/float128-hw4.c: New test. From-SVN: r254740 --- gcc/ChangeLog | 46 ++++++ gcc/config/rs6000/rs6000-builtin.def | 95 +++++++----- gcc/config/rs6000/rs6000-c.c | 21 ++- gcc/config/rs6000/rs6000.c | 111 +++++--------- gcc/config/rs6000/vsx.md | 44 +++--- gcc/testsuite/ChangeLog | 4 + .../gcc.target/powerpc/float128-hw4.c | 135 ++++++++++++++++++ 7 files changed, 325 insertions(+), 131 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-hw4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5870587b55f..0acc10027a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,49 @@ +2017-11-14 Michael Meissner + + * 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_): Change float128 built-in + function insns to support both TFmode and KFmode variants. + (xsxsigqp_): Likewise. + (xsiexpqpf_): Likewise. + (xsiexpqp_): Likewise. + (xststdcqp_): Likewise. + (xststdcnegqp_): Likewise. + (xststdcqp_): Likewise. + 2017-11-14 Jan Hubicka * tree-ssa-threadupdate.c (compute_path_counts): Remove diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 1ef98e37012..6842c122528 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -909,6 +909,51 @@ | 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 @@ -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) diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index c397d2060f7..ef21ba32e7a 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -5759,11 +5759,21 @@ 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) { @@ -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); } diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 05c0c8b2919..ab01998c152 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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) diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 335e5c1a670..e48d4b3df78 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -4068,9 +4068,9 @@ ;; ISA 3.0 Binary Floating-Point Support ;; VSX Scalar Extract Exponent Quad-Precision -(define_insn "xsxexpqp" +(define_insn "xsxexpqp_" [(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" @@ -4086,9 +4086,9 @@ [(set_attr "type" "integer")]) ;; VSX Scalar Extract Significand Quad-Precision -(define_insn "xsxsigqp" +(define_insn "xsxsigqp_" [(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" @@ -4104,20 +4104,21 @@ [(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_" + [(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_" + [(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" @@ -4176,11 +4177,11 @@ ;; (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_" [(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))) @@ -4214,11 +4215,11 @@ }) ;; The VSX Scalar Test Negative Quad-Precision -(define_expand "xststdcnegqp" +(define_expand "xststdcnegqp_" [(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))) @@ -4248,11 +4249,12 @@ operands[3] = CONST0_RTX (SImode); }) -(define_insn "*xststdcqp" +(define_insn "*xststdcqp_" [(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" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16836fa4f0e..ec43496dfd3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-11-14 Michael Meissner + + * gcc.target/powerpc/float128-hw4.c: New test. + 2017-11-14 Rainer Orth * 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 index 00000000000..be5d0d6eef4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw4.c @@ -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} } } */ -- 2.30.2