This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Add builtin for unordered TFmode compare for PA hpux.
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 11 Jun 2004 19:21:09 -0400 (EDT)
- Subject: [committed] Add builtin for unordered TFmode compare for PA hpux.
Various testcases on the trunk were failing because of a lack of
a builtin for unordered TFmode compares. This patch adds the builtin
and defines the magic values for the call to the hpux _U_Qfcmp library
function.
Tested on hppa2.0w-hp-hpux11.11 with no regressions. Installed to
trunk.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2004-06-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (pa_hpux_init_libfunc): Add support for unord_optab.
* pa/quadlib.c (enum qfcmp_magic): Define magic values for call to
_U_Qfcmp library function.
(_U_Qfltgt, _U_Qfunle, _U_Qfunlt, _U_Qfunge, _U_Qfungt, _U_Qfuneq,
_U_Qfunord, _U_Qford): Add more TFmode builtin compare functions.
Index: config/pa/pa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.250
diff -u -3 -p -r1.250 pa.c
--- config/pa/pa.c 11 Jun 2004 22:46:12 -0000 1.250
+++ config/pa/pa.c 11 Jun 2004 22:57:32 -0000
@@ -5467,6 +5467,7 @@ pa_hpux_init_libfuncs (void)
set_optab_libfunc (ge_optab, TFmode, "_U_Qfge");
set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
+ set_optab_libfunc (unord_optab, TFmode, "_U_Qfunord");
set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
Index: config/pa/quadlib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/quadlib.c,v
retrieving revision 1.6
diff -u -3 -p -r1.6 quadlib.c
--- config/pa/quadlib.c 23 Aug 2003 01:32:59 -0000 1.6
+++ config/pa/quadlib.c 11 Jun 2004 22:57:32 -0000
@@ -1,5 +1,5 @@
/* Subroutines for long double support.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -27,6 +27,17 @@ along with GCC; see the file COPYING. I
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* 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. */
+enum qfcmp_magic {
+ QCMP_INV = 1, /* Raise FP_INVALID on SNaN as a side effect. */
+ QCMP_UNORD = 2,
+ QCMP_EQ = 4,
+ QCMP_LT = 8,
+ QCMP_GT = 16
+} magic;
+
int _U_Qfcmp (long double a, long double b, int);
long _U_Qfcnvfxt_quad_to_sgl (long double);
@@ -36,8 +47,19 @@ int _U_Qfgt (long double, long double);
int _U_Qfge (long double, long double);
int _U_Qflt (long double, long double);
int _U_Qfle (long double, long double);
+int _U_Qfltgt (long double, long double);
+int _U_Qfunle (long double, long double);
+int _U_Qfunlt (long double, long double);
+int _U_Qfunge (long double, long double);
+int _U_Qfungt (long double, long double);
+int _U_Qfuneq (long double, long double);
+int _U_Qfunord (long double, long double);
+int _U_Qford (long double, long double);
+
int _U_Qfcomp (long double, long double);
+
long double _U_Qfneg (long double);
+
#ifdef __LP64__
int __U_Qfcnvfxt_quad_to_sgl (long double);
#endif
@@ -47,49 +69,98 @@ unsigned long long _U_Qfcnvfxt_quad_to_u
int
_U_Qfeq (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 4) != 0);
+ return (_U_Qfcmp (a, b, QCMP_EQ) != 0);
}
int
_U_Qfne (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 4) == 0);
+ return (_U_Qfcmp (a, b, QCMP_EQ) == 0);
}
int
_U_Qfgt (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 17) != 0);
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_GT) != 0);
}
int
_U_Qfge (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 21) != 0);
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_GT) != 0);
}
int
_U_Qflt (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 9) != 0);
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT) != 0);
}
int
_U_Qfle (long double a, long double b)
{
- return (_U_Qfcmp (a, b, 13) != 0);
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT) != 0);
+}
+
+int
+_U_Qfltgt (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT | QCMP_GT) != 0);
+}
+
+int
+_U_Qfunle (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_LT) != 0);
+}
+
+int
+_U_Qfunlt (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_LT) != 0);
+}
+
+int
+_U_Qfunge (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0);
+}
+
+int
+_U_Qfungt (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_GT) != 0);
+}
+
+int
+_U_Qfuneq (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ) != 0);
+}
+
+int
+_U_Qfunord (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD) != 0);
+}
+
+int
+_U_Qford (long double a, long double b)
+{
+ return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT | QCMP_GT) != 0);
}
int
_U_Qfcomp (long double a, long double b)
{
- if (_U_Qfcmp (a, b, 4) == 0)
+ if (_U_Qfcmp (a, b, QCMP_EQ) == 0)
return 0;
- return (_U_Qfcmp (a, b, 22) != 0 ? 1 : -1);
+ return (_U_Qfcmp (a, b, QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0 ? 1 : -1);
}
+/* This violates the IEEE standard. It is better to multiply by -1.0L. */
long double
_U_Qfneg (long double a)
{