pa.c (pa_hpux_init_libfunc): Add support for unord_optab.
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Fri, 11 Jun 2004 23:09:58 +0000 (23:09 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Fri, 11 Jun 2004 23:09:58 +0000 (23:09 +0000)
* 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.

From-SVN: r83004

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/quadlib.c

index 0a29cd904e6c8649b8fc25221e23866f38e38f45..39fe01a40e430e644f92ab25b754c7807a3dfd06 100644 (file)
@@ -1,5 +1,11 @@
 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.
+
        * pa.c (legitimize_pic_address): Use UNSPEC_DLTIND14R to identify
        unspec used for loading address from DLT.
        * pa.md: Define constants for the uses of UNSPEC and UNSPEC_VOLATILE.
index 54030a23832786cb16198f3a6328b192cb206194..8bae9e32ad7ce6f9730fd85513a659a94070b98f 100644 (file)
@@ -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 cfec5e9723c9f8a87c0896c3df6d7a754b4f7dc0..6dbfdcfe9a58877489ee25a057814bbf6bf2c03f 100644 (file)
@@ -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.  If not, write to
 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_udbl(long double);
 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)
 {