(root)/
gcc-13.2.0/
libgcc/
config/
pa/
quadlib.c
       1  /* Subroutines for long double support.
       2     Copyright (C) 2000-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC is free software; you can redistribute it and/or modify
       7  it under the terms of the GNU General Public License as published by
       8  the Free Software Foundation; either version 3, or (at your option)
       9  any later version.
      10  
      11  GCC is distributed in the hope that it will be useful,
      12  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  GNU General Public License for more details.
      15  
      16  Under Section 7 of GPL version 3, you are granted additional
      17  permissions described in the GCC Runtime Library Exception, version
      18  3.1, as published by the Free Software Foundation.
      19  
      20  You should have received a copy of the GNU General Public License and
      21  a copy of the GCC Runtime Library Exception along with this program;
      22  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  <http://www.gnu.org/licenses/>.  */
      24  
      25  /* HPUX TFmode compare requires a library call to _U_Qfcmp.  It takes
      26     a magic number as its third argument which indicates what to do.
      27     The return value is an integer to be compared against zero.  The
      28     comparison conditions are the same as those listed in Table 8-12
      29     of the PA-RISC 2.0 Architecture book for the fcmp instruction.  */
      30  
      31  /* Raise FP_INVALID on SNaN as a side effect.  */
      32  #define QCMP_INV 1
      33  
      34  /* Comparison relations.  */
      35  #define QCMP_UNORD 2
      36  #define QCMP_EQ 4
      37  #define QCMP_LT 8
      38  #define QCMP_GT 16
      39  
      40  int _U_Qfcmp (long double a, long double b, int);
      41  long _U_Qfcnvfxt_quad_to_sgl (long double);
      42  
      43  int _U_Qfeq (long double, long double);
      44  int _U_Qfne (long double, long double);
      45  int _U_Qfgt (long double, long double);
      46  int _U_Qfge (long double, long double);
      47  int _U_Qflt (long double, long double);
      48  int _U_Qfle (long double, long double);
      49  int _U_Qfltgt (long double, long double);
      50  int _U_Qfunle (long double, long double);
      51  int _U_Qfunlt (long double, long double);
      52  int _U_Qfunge (long double, long double);
      53  int _U_Qfungt (long double, long double);
      54  int _U_Qfuneq (long double, long double);
      55  int _U_Qfunord (long double, long double);
      56  int _U_Qford (long double, long double);
      57  
      58  int _U_Qfcomp (long double, long double);
      59  
      60  long double _U_Qfneg (long double);
      61  long double _U_Qfcopysign (long double, long double);
      62  
      63  #ifdef __LP64__
      64  int __U_Qfcnvfxt_quad_to_sgl (long double);
      65  #endif
      66  unsigned int _U_Qfcnvfxt_quad_to_usgl(long double);
      67  long double _U_Qfcnvxf_usgl_to_quad (unsigned int);
      68  unsigned long long _U_Qfcnvfxt_quad_to_udbl(long double);
      69  long double _U_Qfcnvxf_udbl_to_quad (unsigned long long);
      70  
      71  int
      72  _U_Qfeq (long double a, long double b)
      73  {
      74    return (_U_Qfcmp (a, b, QCMP_EQ) != 0);
      75  }
      76  
      77  int
      78  _U_Qfne (long double a, long double b)
      79  {
      80    return (_U_Qfcmp (a, b, QCMP_EQ) == 0);
      81  }
      82  	
      83  int
      84  _U_Qfgt (long double a, long double b)
      85  {
      86    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_GT) != 0);
      87  }
      88  
      89  int
      90  _U_Qfge (long double a, long double b)
      91  {
      92    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_GT) != 0);
      93  }
      94  
      95  int
      96  _U_Qflt (long double a, long double b)
      97  {
      98    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT) != 0);
      99  }
     100  
     101  int
     102  _U_Qfle (long double a, long double b)
     103  {
     104    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT) != 0);
     105  }
     106  
     107  int
     108  _U_Qfltgt (long double a, long double b)
     109  {
     110    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT | QCMP_GT) != 0);
     111  }
     112  
     113  int
     114  _U_Qfunle (long double a, long double b)
     115  {
     116    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_LT) != 0);
     117  }
     118  
     119  int
     120  _U_Qfunlt (long double a, long double b)
     121  {
     122    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_LT) != 0);
     123  }
     124  
     125  int
     126  _U_Qfunge (long double a, long double b)
     127  {
     128    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0);
     129  }
     130  
     131  int
     132  _U_Qfungt (long double a, long double b)
     133  {
     134    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_GT) != 0);
     135  }
     136  
     137  int
     138  _U_Qfuneq (long double a, long double b)
     139  {
     140    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ) != 0);
     141  }
     142  
     143  int
     144  _U_Qfunord (long double a, long double b)
     145  {
     146    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD) != 0);
     147  }
     148  
     149  int
     150  _U_Qford (long double a, long double b)
     151  {
     152    return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT | QCMP_GT) != 0);
     153  }
     154  
     155  int
     156  _U_Qfcomp (long double a, long double b)
     157  {
     158    if (_U_Qfcmp (a, b, QCMP_EQ) == 0)
     159      return 0;
     160  
     161    return (_U_Qfcmp (a, b, QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0 ? 1 : -1);
     162  }
     163  
     164  /* Negate long double A.  */
     165  long double
     166  _U_Qfneg (long double a)
     167  {
     168    union
     169     {
     170       long double ld;
     171       int i[4];
     172     } u;
     173  
     174    u.ld = a;
     175    u.i[0] ^= 0x80000000;
     176    return u.ld;
     177  }
     178  
     179  /* Return long double A with sign changed to sign of long double B.  */
     180  long double
     181  _U_Qfcopysign (long double a, long double b)
     182  {
     183    union
     184     {
     185       long double ld;
     186       int i[4];
     187     } ua, ub;
     188  
     189    ua.ld = a;
     190    ub.ld = b;
     191    ua.i[0] &= 0x7fffffff;
     192    ua.i[0] |= (0x80000000 & ub.i[0]);
     193    return ua.ld;
     194  }
     195  
     196  #ifdef __LP64__
     197  /* This routine is only necessary for the PA64 port; for reasons unknown
     198     _U_Qfcnvfxt_quad_to_sgl returns the integer in the high 32bits of the
     199     return value.  Ugh.  */
     200  int
     201  __U_Qfcnvfxt_quad_to_sgl (long double a)
     202  {
     203    return _U_Qfcnvfxt_quad_to_sgl (a) >> 32;
     204  }
     205  #endif
     206  
     207  /* HP only has signed conversion in the C library, so need to synthesize
     208     unsigned versions.  */
     209  unsigned int
     210  _U_Qfcnvfxt_quad_to_usgl (long double a)
     211  {
     212    extern long long _U_Qfcnvfxt_quad_to_dbl (long double a);
     213    return (unsigned int) _U_Qfcnvfxt_quad_to_dbl (a);
     214  }
     215  
     216  long double
     217  _U_Qfcnvxf_usgl_to_quad (unsigned int a)
     218  {
     219    extern long double _U_Qfcnvxf_dbl_to_quad (long long);
     220    return _U_Qfcnvxf_dbl_to_quad ((long long) a);
     221  }
     222  
     223  typedef union {
     224      unsigned long long u[2];
     225      long double d[1];
     226  } quad_type;
     227  
     228  unsigned long long
     229  _U_Qfcnvfxt_quad_to_udbl (long double a)
     230  {
     231    extern quad_type _U_Qfcnvfxt_quad_to_quad (long double a);
     232    quad_type u;
     233    u = _U_Qfcnvfxt_quad_to_quad(a);
     234    return u.u[1];
     235  }
     236  
     237  long double
     238  _U_Qfcnvxf_udbl_to_quad (unsigned long long a)
     239  {
     240    extern long double _U_Qfcnvxf_quad_to_quad (quad_type a);
     241    quad_type u;
     242    u.u[0] = 0;
     243    u.u[1] = a;
     244    return _U_Qfcnvxf_quad_to_quad (u);
     245  }