2004-05-19  H.J. Lu  <hongjiu.lu@intel.com>

	* config/ia64/hpux.h (TARGET_INIT_LIBFUNCS): Undef first.

	* config/ia64/ia64.c (ia64_expand_compare): Don't check
	TARGET_HPUX for TFmode compare. Abort if op0 is in TFmode and
	cmptf_libfunc isn't set.
	(ia64_init_libfuncs): New. Rename TFmode libfuncs using the
	HPUX conventions.
	(ia64_hpux_init_libfuncs): Use it.
	(ia64_sysv4_init_libfuncs): New.

	* config/ia64/sysv4.h (TARGET_INIT_LIBFUNCS): New. Defined as
	ia64_sysv4_init_libfuncs.

--- gcc/config/ia64/hpux.h.float128	2004-04-27 10:59:04.000000000 -0700
+++ gcc/config/ia64/hpux.h	2004-05-17 22:14:50.000000000 -0700
@@ -202,6 +202,7 @@ do {								\
 #undef TARGET_C99_FUNCTIONS
 #define TARGET_C99_FUNCTIONS  1
 
+#undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
 
 #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
--- gcc/config/ia64/ia64.c.float128	2004-05-17 22:14:47.000000000 -0700
+++ gcc/config/ia64/ia64.c	2004-05-19 15:48:51.000000000 -0700
@@ -289,8 +289,11 @@ static void ia64_hpux_file_end (void)
      ATTRIBUTE_UNUSED;
 static void ia64_hpux_init_libfuncs (void)
      ATTRIBUTE_UNUSED;
+static void ia64_sysv4_init_libfuncs (void)
+     ATTRIBUTE_UNUSED;
 static void ia64_vms_init_libfuncs (void)
      ATTRIBUTE_UNUSED;
+static void ia64_init_libfuncs (void);
 
 static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
 static void ia64_encode_section_info (tree, rtx, int);
@@ -1680,7 +1683,7 @@ ia64_expand_compare (enum rtx_code code,
   /* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
      magic number as its third argument, that indicates what to do.
      The return value is an integer to be compared against zero.  */
-  else if (TARGET_HPUX && GET_MODE (op0) == TFmode)
+  else if (GET_MODE (op0) == TFmode)
     {
       enum qfcmp_magic {
 	QCMP_INV = 1,	/* Raise FP_INVALID on SNaN as a side effect.  */
@@ -1691,7 +1694,7 @@ ia64_expand_compare (enum rtx_code code,
       } magic;
       enum rtx_code ncode;
       rtx ret, insns;
-      if (GET_MODE (op1) != TFmode)
+      if (!cmptf_libfunc || GET_MODE (op1) != TFmode)
 	abort ();
       switch (code)
 	{
@@ -10488,14 +10491,11 @@ ia64_hpux_file_end (void)
 static void
 ia64_hpux_init_libfuncs (void)
 {
-  set_optab_libfunc (add_optab, TFmode, "_U_Qfadd");
-  set_optab_libfunc (sub_optab, TFmode, "_U_Qfsub");
-  set_optab_libfunc (smul_optab, TFmode, "_U_Qfmpy");
-  set_optab_libfunc (sdiv_optab, TFmode, "_U_Qfdiv");
+  ia64_init_libfuncs ();
+
   set_optab_libfunc (smin_optab, TFmode, "_U_Qfmin");
   set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
   set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
-  set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
 
   /* ia64_expand_compare uses this.  */
   cmptf_libfunc = init_one_libfunc ("_U_Qfcmp");
@@ -10507,21 +10507,6 @@ ia64_hpux_init_libfuncs (void)
   set_optab_libfunc (ge_optab, TFmode, 0);
   set_optab_libfunc (lt_optab, TFmode, 0);
   set_optab_libfunc (le_optab, TFmode, 0);
-
-  set_conv_libfunc (sext_optab,   TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
-  set_conv_libfunc (sext_optab,   TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
-  set_conv_libfunc (sext_optab,   TFmode, XFmode, "_U_Qfcnvff_f80_to_quad");
-  set_conv_libfunc (trunc_optab,  SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
-  set_conv_libfunc (trunc_optab,  DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
-  set_conv_libfunc (trunc_optab,  XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");
-
-  set_conv_libfunc (sfix_optab,   SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
-  set_conv_libfunc (sfix_optab,   DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
-  set_conv_libfunc (ufix_optab,   SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
-  set_conv_libfunc (ufix_optab,   DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");
-
-  set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
-  set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
 }
 
 /* Rename the division and modulus functions in VMS.  */
@@ -10538,6 +10523,56 @@ ia64_vms_init_libfuncs (void)
   set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
   set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
 }
+
+/* Rename the TFmode libfuncs available from soft-fp in glibc using
+   the HPUX conventions.  */
+
+static void
+ia64_sysv4_init_libfuncs (void)
+{
+  ia64_init_libfuncs ();
+
+  /* These functions are not part of the HPUX TFmode interface.  We
+     use them instead of _U_Qfcmp, which doesn't work the way we
+     expect.  */
+  set_optab_libfunc (eq_optab, TFmode, "_U_Qfeq");
+  set_optab_libfunc (ne_optab, TFmode, "_U_Qfne");
+  set_optab_libfunc (gt_optab, TFmode, "_U_Qfgt");
+  set_optab_libfunc (ge_optab, TFmode, "_U_Qfge");
+  set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
+  set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
+
+  /* We leave out _U_Qfmin, _U_Qfmax and _U_Qfabs since soft-fp in
+     glibc doesn't have them.  */
+}
+
+/* Rename the TFmode libfuncs using the HPUX conventions. __divtf3 is
+   used for XFmode. We need to keep it for backward compatibility. */
+
+static void
+ia64_init_libfuncs (void)
+{
+  set_optab_libfunc (add_optab, TFmode, "_U_Qfadd");
+  set_optab_libfunc (sub_optab, TFmode, "_U_Qfsub");
+  set_optab_libfunc (smul_optab, TFmode, "_U_Qfmpy");
+  set_optab_libfunc (sdiv_optab, TFmode, "_U_Qfdiv");
+  set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
+
+  set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
+  set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
+  set_conv_libfunc (sext_optab, TFmode, XFmode, "_U_Qfcnvff_f80_to_quad");
+  set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
+  set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
+  set_conv_libfunc (trunc_optab, XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");
+
+  set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
+  set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
+  set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
+  set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");
+
+  set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
+  set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
+}
 
 /* Switch to the section to which we should output X.  The only thing
    special we do here is to honor small data.  */
--- gcc/config/ia64/sysv4.h.float128	2003-11-04 16:50:09.000000000 -0800
+++ gcc/config/ia64/sysv4.h	2004-05-17 22:14:50.000000000 -0700
@@ -1,5 +1,7 @@
 /* Override definitions in elfos.h/svr4.h to be correct for IA64.  */
 
+#define TARGET_INIT_LIBFUNCS ia64_sysv4_init_libfuncs
+
 /* We want DWARF2 as specified by the IA64 ABI.  */
 #undef PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
