===================================================================
@@ -16036,75 +16036,184 @@ rs6000_common_init_builtins (void)
}
}
+/* Set up AIX/Darwin/64-bit Linux quad floating point routines. */
static void
-rs6000_init_libfuncs (void)
+init_float128_ibm (machine_mode mode)
{
- if (!TARGET_IEEEQUAD)
- /* AIX/Darwin/64-bit Linux quad floating point routines. */
- if (!TARGET_XL_COMPAT)
- {
- set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
- set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
- set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
- set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
+ if (!TARGET_XL_COMPAT)
+ {
+ set_optab_libfunc (add_optab, mode, "__gcc_qadd");
+ set_optab_libfunc (sub_optab, mode, "__gcc_qsub");
+ set_optab_libfunc (smul_optab, mode, "__gcc_qmul");
+ set_optab_libfunc (sdiv_optab, mode, "__gcc_qdiv");
- if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
- {
- set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
- set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
- set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
- set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
- set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
- set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
- set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
-
- set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
- set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
- set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
- set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
- set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
- set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
- set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
- set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
- }
+ if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
+ {
+ set_optab_libfunc (neg_optab, mode, "__gcc_qneg");
+ set_optab_libfunc (eq_optab, mode, "__gcc_qeq");
+ set_optab_libfunc (ne_optab, mode, "__gcc_qne");
+ set_optab_libfunc (gt_optab, mode, "__gcc_qgt");
+ set_optab_libfunc (ge_optab, mode, "__gcc_qge");
+ set_optab_libfunc (lt_optab, mode, "__gcc_qlt");
+ set_optab_libfunc (le_optab, mode, "__gcc_qle");
- if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
- set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
- }
- else
- {
- set_optab_libfunc (add_optab, TFmode, "_xlqadd");
- set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
- set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
- set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
- }
+ set_conv_libfunc (sext_optab, mode, SFmode, "__gcc_stoq");
+ set_conv_libfunc (sext_optab, mode, DFmode, "__gcc_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, mode, "__gcc_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, mode, "__gcc_qtod");
+ set_conv_libfunc (sfix_optab, SImode, mode, "__gcc_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, mode, "__gcc_qtou");
+ set_conv_libfunc (sfloat_optab, mode, SImode, "__gcc_itoq");
+ set_conv_libfunc (ufloat_optab, mode, SImode, "__gcc_utoq");
+ }
+
+ if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
+ set_optab_libfunc (unord_optab, mode, "__gcc_qunord");
+ }
else
{
- /* 32-bit SVR4 quad floating point routines. */
+ set_optab_libfunc (add_optab, mode, "_xlqadd");
+ set_optab_libfunc (sub_optab, mode, "_xlqsub");
+ set_optab_libfunc (smul_optab, mode, "_xlqmul");
+ set_optab_libfunc (sdiv_optab, mode, "_xlqdiv");
+ }
+
+ /* Add various conversions for IFmode to use the traditional TFmode
+ names. */
+ if (mode == IFmode)
+ {
+ set_conv_libfunc (sext_optab, mode, SDmode, "__dpd_extendsdtf2");
+ set_conv_libfunc (sext_optab, mode, DDmode, "__dpd_extendddtf2");
+ set_conv_libfunc (trunc_optab, mode, TDmode, "__dpd_trunctftd2");
+ set_conv_libfunc (trunc_optab, SDmode, mode, "__dpd_trunctfsd2");
+ set_conv_libfunc (trunc_optab, DDmode, mode, "__dpd_trunctfdd2");
+ set_conv_libfunc (sext_optab, TDmode, mode, "__dpd_extendtdtf2");
+
+ if (TARGET_POWERPC64)
+ {
+ set_conv_libfunc (sfix_optab, TImode, mode, "__fixtfti");
+ set_conv_libfunc (ufix_optab, TImode, mode, "__fixunstfti");
+ set_conv_libfunc (sfloat_optab, mode, TImode, "__floattitf");
+ set_conv_libfunc (ufloat_optab, mode, TImode, "__floatuntitf");
+ }
+ }
+}
+
+/* Set up IEEE 128-bit floating point routines. Use different names if the
+ arguments can be passed in a vector register. The historical PowerPC
+ implementation of IEEE 128-bit floating point used _q_<op> for the names, so
+ continue to use that if we aren't using vector registers to pass IEEE
+ 128-bit floating point. */
+
+static void
+init_float128_ieee (machine_mode mode)
+{
+ if (FLOAT128_VECTOR_P (mode))
+ {
+ set_optab_libfunc (add_optab, mode, "__addkf3");
+ set_optab_libfunc (sub_optab, mode, "__subkf3");
+ set_optab_libfunc (neg_optab, mode, "__negkf2");
+ set_optab_libfunc (smul_optab, mode, "__mulkf3");
+ set_optab_libfunc (sdiv_optab, mode, "__divkf3");
+ set_optab_libfunc (sqrt_optab, mode, "__sqrtkf2");
+ set_optab_libfunc (abs_optab, mode, "__abstkf2");
- set_optab_libfunc (add_optab, TFmode, "_q_add");
- set_optab_libfunc (sub_optab, TFmode, "_q_sub");
- set_optab_libfunc (neg_optab, TFmode, "_q_neg");
- set_optab_libfunc (smul_optab, TFmode, "_q_mul");
- set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
+ set_optab_libfunc (eq_optab, mode, "__eqkf2");
+ set_optab_libfunc (ne_optab, mode, "__nekf2");
+ set_optab_libfunc (gt_optab, mode, "__gtkf2");
+ set_optab_libfunc (ge_optab, mode, "__gekf2");
+ set_optab_libfunc (lt_optab, mode, "__ltkf2");
+ set_optab_libfunc (le_optab, mode, "__lekf2");
+ set_optab_libfunc (unord_optab, mode, "__unordkf2");
+ set_optab_libfunc (cmp_optab, mode, "__cmpokf2"); /* fcmpo */
+ set_optab_libfunc (ucmp_optab, mode, "__cmpukf2"); /* fcmpu */
+
+ set_conv_libfunc (sext_optab, mode, SFmode, "__extendsfkf2");
+ set_conv_libfunc (sext_optab, mode, DFmode, "__extenddfkf2");
+ set_conv_libfunc (trunc_optab, SFmode, mode, "__trunckfsf2");
+ set_conv_libfunc (trunc_optab, DFmode, mode, "__trunckfdf2");
+
+ set_conv_libfunc (sext_optab, mode, IFmode, "__extendtfkf2");
+ if (mode != TFmode && FLOAT128_IBM_P (TFmode))
+ set_conv_libfunc (sext_optab, mode, TFmode, "__extendtfkf2");
+
+ set_conv_libfunc (trunc_optab, IFmode, mode, "__trunckftf2");
+ if (mode != TFmode && FLOAT128_IBM_P (TFmode))
+ set_conv_libfunc (trunc_optab, TFmode, mode, "__trunckftf2");
+
+ set_conv_libfunc (sext_optab, mode, SDmode, "__dpd_extendsdkf2");
+ set_conv_libfunc (sext_optab, mode, DDmode, "__dpd_extendddkf2");
+ set_conv_libfunc (trunc_optab, mode, TDmode, "__dpd_trunckftd2");
+ set_conv_libfunc (trunc_optab, SDmode, mode, "__dpd_trunckfsd2");
+ set_conv_libfunc (trunc_optab, DDmode, mode, "__dpd_trunckfdd2");
+ set_conv_libfunc (sext_optab, TDmode, mode, "__dpd_extendtdkf2");
+
+ set_conv_libfunc (sfix_optab, SImode, mode, "__fixkfsi");
+ set_conv_libfunc (ufix_optab, SImode, mode, "__fixunskfsi");
+ set_conv_libfunc (sfix_optab, DImode, mode, "__fixkfdi");
+ set_conv_libfunc (ufix_optab, DImode, mode, "__fixunskfdi");
+
+ set_conv_libfunc (sfloat_optab, mode, SImode, "__floatsikf");
+ set_conv_libfunc (ufloat_optab, mode, SImode, "__floatunsikf");
+ set_conv_libfunc (sfloat_optab, mode, DImode, "__floatdikf");
+ set_conv_libfunc (ufloat_optab, mode, DImode, "__floatundikf");
+
+ if (TARGET_POWERPC64)
+ {
+ set_conv_libfunc (sfix_optab, TImode, mode, "__fixkfti");
+ set_conv_libfunc (ufix_optab, TImode, mode, "__fixunskfti");
+ set_conv_libfunc (sfloat_optab, mode, TImode, "__floattikf");
+ set_conv_libfunc (ufloat_optab, mode, TImode, "__floatuntikf");
+ }
+ }
+
+ else
+ {
+ set_optab_libfunc (add_optab, mode, "_q_add");
+ set_optab_libfunc (sub_optab, mode, "_q_sub");
+ set_optab_libfunc (neg_optab, mode, "_q_neg");
+ set_optab_libfunc (smul_optab, mode, "_q_mul");
+ set_optab_libfunc (sdiv_optab, mode, "_q_div");
if (TARGET_PPC_GPOPT)
- set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
+ set_optab_libfunc (sqrt_optab, mode, "_q_sqrt");
- set_optab_libfunc (eq_optab, TFmode, "_q_feq");
- set_optab_libfunc (ne_optab, TFmode, "_q_fne");
- set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
- set_optab_libfunc (ge_optab, TFmode, "_q_fge");
- set_optab_libfunc (lt_optab, TFmode, "_q_flt");
- set_optab_libfunc (le_optab, TFmode, "_q_fle");
-
- set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
- set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
- set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
- set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
- set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
- set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
- set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
- set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
+ set_optab_libfunc (eq_optab, mode, "_q_feq");
+ set_optab_libfunc (ne_optab, mode, "_q_fne");
+ set_optab_libfunc (gt_optab, mode, "_q_fgt");
+ set_optab_libfunc (ge_optab, mode, "_q_fge");
+ set_optab_libfunc (lt_optab, mode, "_q_flt");
+ set_optab_libfunc (le_optab, mode, "_q_fle");
+
+ set_conv_libfunc (sext_optab, mode, SFmode, "_q_stoq");
+ set_conv_libfunc (sext_optab, mode, DFmode, "_q_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, mode, "_q_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, mode, "_q_qtod");
+ set_conv_libfunc (sfix_optab, SImode, mode, "_q_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, mode, "_q_qtou");
+ set_conv_libfunc (sfloat_optab, mode, SImode, "_q_itoq");
+ set_conv_libfunc (ufloat_optab, mode, SImode, "_q_utoq");
+ }
+}
+
+static void
+rs6000_init_libfuncs (void)
+{
+ /* __float128 support. */
+ if (TARGET_FLOAT128)
+ {
+ init_float128_ibm (IFmode);
+ init_float128_ieee (KFmode);
+ }
+
+ /* AIX/Darwin/64-bit Linux quad floating point routines. */
+ if (TARGET_LONG_DOUBLE_128)
+ {
+ if (!TARGET_IEEEQUAD)
+ init_float128_ibm (TFmode);
+
+ /* IEEE 128-bit including 32-bit SVR4 quad floating point routines. */
+ else
+ init_float128_ieee (TFmode);
}
}