(root)/
gcc-13.2.0/
libgcc/
config/
rs6000/
quad-float128.h
       1  /* Software floating-point emulation.
       2     Definitions for IEEE Quad Precision on the PowerPC.
       3     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       4     This file is part of the GNU C Library.
       5     Contributed by Michael Meissner (meissner@linux.vnet.ibm.com).
       6  
       7     The GNU C Library is free software; you can redistribute it and/or
       8     modify it under the terms of the GNU Lesser General Public
       9     License as published by the Free Software Foundation; either
      10     version 2.1 of the License, or (at your option) any later version.
      11  
      12     In addition to the permissions in the GNU Lesser General Public
      13     License, the Free Software Foundation gives you unlimited
      14     permission to link the compiled version of this file into
      15     combinations with other programs, and to distribute those
      16     combinations without any restriction coming from the use of this
      17     file.  (The Lesser General Public License restrictions do apply in
      18     other respects; for example, they cover modification of the file,
      19     and distribution when not linked into a combine executable.)
      20  
      21     The GNU C Library is distributed in the hope that it will be useful,
      22     but WITHOUT ANY WARRANTY; without even the implied warranty of
      23     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24     Lesser General Public License for more details.
      25  
      26     You should have received a copy of the GNU Lesser General Public
      27     License along with the GNU C Library; if not, see
      28     <http://www.gnu.org/licenses/>.  */
      29  
      30  /* Override the types for IEEE 128-bit scalar and complex.  We need to use the
      31     same IEEE 128-bit type (either long double or _Float128) for both the
      32     128-bit scalar type and for the base type in _Complex.  Otherwise, if
      33     different types are used, there may be problems in mixing _Complex values
      34     with the scalar value.
      35  
      36     We can't use _Compelx _float128 since GCC doesn't allow it.  It only allows
      37     _Complex for _Float128 or for long double.
      38  
      39     We use _Float128 when long double is IBM double-double or 64-bit, and long
      40     double when long double uses the IEEE 128-bit type.  We need to do this
      41     because the compiler has a built-in prototype for __mulkc3 and __divkc3
      42     using those types.  Since we are declaring these functions here, we need to
      43     use the same type that the compiler uses (i.e. we can't just always use
      44     _Float128).
      45  
      46     Even though the type _Float128 and long double (when long double uses IEEE
      47     128-bits) both hold IEEE 128-bit values, the front ends treat these as two
      48     separate types.
      49  
      50     The extension keyword __float128 is currently problematical because it can
      51     either be a synonym for _Float128 (when long double is IBM) or for long
      52     double (when long double is IEEE).  */
      53  
      54  #ifdef __LONG_DOUBLE_IEEE128__
      55  #define TFtype long double
      56  #define TCtype _Complex long double
      57  
      58  #else
      59  #define TFtype _Float128
      60  #define TCtype _Complex _Float128
      61  #endif
      62  
      63  /* Force the use of the VSX instruction set.  */
      64  #if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
      65  #pragma GCC target ("vsx,float128")
      66  #endif
      67  
      68  #include <stddef.h>
      69  #include <quad.h>
      70  
      71  #define IBM128_TYPE	__ibm128
      72  
      73  /* Add prototypes of the library functions created.  In case the appropriate
      74     int/long types are not declared in scope by the time quad.h is included,
      75     provide our own version.  */
      76  typedef int	 SItype_ppc  __attribute__ ((__mode__ (__SI__)));
      77  typedef int	 DItype_ppc  __attribute__ ((__mode__ (__DI__)));
      78  typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__)));
      79  typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__)));
      80  
      81  #ifdef _ARCH_PPC64
      82  typedef int	 TItype_ppc  __attribute__ ((__mode__ (__TI__)));
      83  typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__)));
      84  #endif
      85  
      86  /* Software emulation functions.  */
      87  extern TFtype __addkf3_sw (TFtype, TFtype);
      88  extern TFtype __subkf3_sw (TFtype, TFtype);
      89  extern TFtype __mulkf3_sw (TFtype, TFtype);
      90  extern TFtype __divkf3_sw (TFtype, TFtype);
      91  extern TFtype __negkf2_sw (TFtype);
      92  extern TFtype __powikf2_sw (TFtype, SItype_ppc);
      93  extern CMPtype __eqkf2_sw (TFtype, TFtype);
      94  extern CMPtype __gekf2_sw (TFtype, TFtype);
      95  extern CMPtype __lekf2_sw (TFtype, TFtype);
      96  extern CMPtype __unordkf2_sw (TFtype, TFtype);
      97  extern TFtype __extendsfkf2_sw (float);
      98  extern TFtype __extenddfkf2_sw (double);
      99  extern float __trunckfsf2_sw (TFtype);
     100  extern double __trunckfdf2_sw (TFtype);
     101  extern SItype_ppc __fixkfsi_sw (TFtype);
     102  extern DItype_ppc __fixkfdi_sw (TFtype);
     103  extern USItype_ppc __fixunskfsi_sw (TFtype);
     104  extern UDItype_ppc __fixunskfdi_sw (TFtype);
     105  extern TFtype __floatsikf_sw (SItype_ppc);
     106  extern TFtype __floatdikf_sw (DItype_ppc);
     107  #ifdef _ARCH_PPC64
     108  extern TFtype __floattikf_sw (TItype_ppc);
     109  #endif
     110  extern TFtype __floatunsikf_sw (USItype_ppc);
     111  extern TFtype __floatundikf_sw (UDItype_ppc);
     112  #ifdef _ARCH_PPC64
     113  extern TFtype __floatuntikf_sw (UTItype_ppc);
     114  extern TItype_ppc __fixkfti_sw (TFtype);
     115  extern UTItype_ppc __fixunskfti_sw (TFtype);
     116  #endif
     117  extern IBM128_TYPE __extendkftf2_sw (TFtype);
     118  extern TFtype __trunctfkf2_sw (IBM128_TYPE);
     119  extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
     120  extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype);
     121  
     122  #ifdef _ARCH_PPC64
     123  extern TItype_ppc __fixkfti (TFtype);
     124  extern UTItype_ppc __fixunskfti (TFtype);
     125  extern TFtype __floattikf (TItype_ppc);
     126  extern TFtype __floatuntikf (UTItype_ppc);
     127  #endif
     128  
     129  /* Functions using the ISA 3.0 hardware support.  If the code is compiled with
     130     -mcpu=power9, it will not use these functions, but if it was compiled with
     131     -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the
     132     hardware instruction.  */
     133  extern TFtype __addkf3_hw (TFtype, TFtype);
     134  extern TFtype __subkf3_hw (TFtype, TFtype);
     135  extern TFtype __mulkf3_hw (TFtype, TFtype);
     136  extern TFtype __divkf3_hw (TFtype, TFtype);
     137  extern TFtype __negkf2_hw (TFtype);
     138  extern TFtype __powikf2_hw (TFtype, SItype_ppc);
     139  extern CMPtype __eqkf2_hw (TFtype, TFtype);
     140  extern CMPtype __gekf2_hw (TFtype, TFtype);
     141  extern CMPtype __lekf2_hw (TFtype, TFtype);
     142  extern CMPtype __unordkf2_hw (TFtype, TFtype);
     143  extern TFtype __extendsfkf2_hw (float);
     144  extern TFtype __extenddfkf2_hw (double);
     145  extern float __trunckfsf2_hw (TFtype);
     146  extern double __trunckfdf2_hw (TFtype);
     147  extern SItype_ppc __fixkfsi_hw (TFtype);
     148  extern DItype_ppc __fixkfdi_hw (TFtype);
     149  extern USItype_ppc __fixunskfsi_hw (TFtype);
     150  extern UDItype_ppc __fixunskfdi_hw (TFtype);
     151  extern TFtype __floatsikf_hw (SItype_ppc);
     152  extern TFtype __floatdikf_hw (DItype_ppc);
     153  #ifdef _ARCH_PPC64
     154  extern TFtype __floattikf_hw (TItype_ppc);
     155  #endif
     156  extern TFtype __floatunsikf_hw (USItype_ppc);
     157  extern TFtype __floatundikf_hw (UDItype_ppc);
     158  #ifdef _ARCH_PPC64
     159  extern TFtype __floatuntikf_hw (UTItype_ppc);
     160  extern TItype_ppc __fixkfti_hw (TFtype);
     161  extern UTItype_ppc __fixunskfti_hw (TFtype);
     162  #endif
     163  extern IBM128_TYPE __extendkftf2_hw (TFtype);
     164  extern TFtype __trunctfkf2_hw (IBM128_TYPE);
     165  extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
     166  extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype);
     167  
     168  /* Ifunc function declarations, to automatically switch between software
     169     emulation and hardware support.  */
     170  extern TFtype __addkf3 (TFtype, TFtype);
     171  extern TFtype __subkf3 (TFtype, TFtype);
     172  extern TFtype __mulkf3 (TFtype, TFtype);
     173  extern TFtype __divkf3 (TFtype, TFtype);
     174  extern TFtype __negkf2 (TFtype);
     175  extern TFtype __powikf2 (TFtype, SItype_ppc);
     176  extern CMPtype __eqkf2 (TFtype, TFtype);
     177  extern CMPtype __nekf2 (TFtype, TFtype);
     178  extern CMPtype __gekf2 (TFtype, TFtype);
     179  extern CMPtype __gtkf2 (TFtype, TFtype);
     180  extern CMPtype __lekf2 (TFtype, TFtype);
     181  extern CMPtype __ltkf2 (TFtype, TFtype);
     182  extern CMPtype __unordkf2 (TFtype, TFtype);
     183  extern TFtype __extendsfkf2 (float);
     184  extern TFtype __extenddfkf2 (double);
     185  extern float __trunckfsf2 (TFtype);
     186  extern double __trunckfdf2 (TFtype);
     187  extern SItype_ppc __fixkfsi (TFtype);
     188  extern DItype_ppc __fixkfdi (TFtype);
     189  extern USItype_ppc __fixunskfsi (TFtype);
     190  extern UDItype_ppc __fixunskfdi (TFtype);
     191  extern TFtype __floatsikf (SItype_ppc);
     192  extern TFtype __floatdikf (DItype_ppc);
     193  #ifdef _ARCH_PPC64
     194  extern TFtype __floattikf (TItype_ppc);
     195  #endif
     196  extern TFtype __floatunsikf (USItype_ppc);
     197  extern TFtype __floatundikf (UDItype_ppc);
     198  #ifdef _ARCH_PPC64
     199  extern TFtype __floatuntikf (UTItype_ppc);
     200  extern TItype_ppc __fixkfti (TFtype);
     201  extern UTItype_ppc __fixunskfti (TFtype);
     202  #endif
     203  extern IBM128_TYPE __extendkftf2 (TFtype);
     204  extern TFtype __trunctfkf2 (IBM128_TYPE);
     205  
     206  /* Complex __float128 built on __float128 interfaces.  */
     207  extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
     208  extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
     209  
     210  /* Convert IEEE 128-bit floating point to/from string.  We explicitly use
     211     _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
     212     with long double being IBM 128.  */
     213  extern _Float128 __strtokf (const char *, char **);
     214  extern int __strfromkf (char *restrict, size_t, const char *restrict,
     215  			_Float128);
     216  
     217  /* Implementation of conversions between __ibm128 and __float128, to allow the
     218     same code to be used on systems with IEEE 128-bit emulation and with IEEE
     219     128-bit hardware support.  */
     220  
     221  union ibm128_union {
     222    IBM128_TYPE ibm128;
     223    double dbl[2];
     224  };
     225  
     226  #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE)				\
     227  {									\
     228    double __high, __low;							\
     229    TFtype __value = (VALUE);						\
     230    union ibm128_union u;							\
     231  									\
     232    __high = (double) __value;						\
     233    if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
     234      __low = 0.0;							\
     235  									\
     236    else									\
     237      {									\
     238        double __high_temp;						\
     239  									\
     240        __low = (double) (__value - (TFtype) __high);			\
     241        /* Renormalize low/high and move them into canonical IBM long	\
     242  	 double form.  */						\
     243        __high_temp = __high + __low;					\
     244        __low = (__high - __high_temp) + __low;				\
     245        __high = __high_temp;						\
     246      }									\
     247  									\
     248    u.dbl[0] = __high;							\
     249    u.dbl[1] = __low;							\
     250    RESULT = u.ibm128;							\
     251  }
     252  
     253  #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE)				\
     254  {									\
     255    union ibm128_union u;							\
     256    double __high, __low;							\
     257  									\
     258    u.ibm128 = (VALUE);							\
     259    __high = u.dbl[0];							\
     260    __low = u.dbl[1];							\
     261  									\
     262    /* Handle the special cases of NAN and infinity.  */			\
     263    if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
     264      RESULT = (TFtype) __high;						\
     265  									\
     266    /* If low is 0.0, there no need to do the add.  In addition,		\
     267       avoiding the add produces the correct sign if high is -0.0.  */	\
     268    else if (__low == 0.0)						\
     269      RESULT = (TFtype) __high;						\
     270  									\
     271    else									\
     272      RESULT = ((TFtype) __high) + ((TFtype) __low);			\
     273  }