Home | History | Annotate | Line # | Download | only in soft-fp
      1  1.1  mrg /* Software floating-point emulation.
      2  1.1  mrg    Convert a _BitInt to _Decimal32.
      3  1.1  mrg 
      4  1.1  mrg    Copyright (C) 2023 Free Software Foundation, Inc.
      5  1.1  mrg 
      6  1.1  mrg This file is part of GCC.
      7  1.1  mrg 
      8  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      9  1.1  mrg the terms of the GNU General Public License as published by the Free
     10  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     11  1.1  mrg version.
     12  1.1  mrg 
     13  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16  1.1  mrg for more details.
     17  1.1  mrg 
     18  1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     19  1.1  mrg permissions described in the GCC Runtime Library Exception, version
     20  1.1  mrg 3.1, as published by the Free Software Foundation.
     21  1.1  mrg 
     22  1.1  mrg You should have received a copy of the GNU General Public License and
     23  1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     24  1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     25  1.1  mrg <http://www.gnu.org/licenses/>.  */
     26  1.1  mrg 
     27  1.1  mrg #include "soft-fp.h"
     28  1.1  mrg #include "bitint.h"
     29  1.1  mrg 
     30  1.1  mrg #ifdef __BITINT_MAXWIDTH__
     31  1.1  mrg extern _Decimal32 __bid_floatbitintsd (const UBILtype *, SItype);
     32  1.1  mrg 
     33  1.1  mrg _Decimal32
     34  1.1  mrg __bid_floatbitintsd (const UBILtype *i, SItype iprec)
     35  1.1  mrg {
     36  1.1  mrg   iprec = bitint_reduce_prec (&i, iprec);
     37  1.1  mrg   USItype aiprec = iprec < 0 ? -iprec : iprec;
     38  1.1  mrg   USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
     39  1.1  mrg   USItype idx = BITINT_END (0, in - 1);
     40  1.1  mrg   UBILtype msb = i[idx];
     41  1.1  mrg   USItype mantissa;
     42  1.1  mrg   SItype exponent = 0;
     43  1.1  mrg   UBILtype inexact = 0;
     44  1.1  mrg   union { _Decimal32 d; USItype u; } u, ui;
     45  1.1  mrg   if (aiprec % BIL_TYPE_SIZE)
     46  1.1  mrg     {
     47  1.1  mrg       if (iprec > 0)
     48  1.1  mrg 	msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1;
     49  1.1  mrg       else
     50  1.1  mrg 	msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE);
     51  1.1  mrg     }
     52  1.1  mrg   if (iprec < 0)
     53  1.1  mrg     {
     54  1.1  mrg       SItype n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb);
     55  1.1  mrg       aiprec = (in - 1) * BIL_TYPE_SIZE + n;
     56  1.1  mrg     }
     57  1.1  mrg   else if (msb == 0)
     58  1.1  mrg     aiprec = 1;
     59  1.1  mrg   else
     60  1.1  mrg     {
     61  1.1  mrg       SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb);
     62  1.1  mrg       aiprec = (in - 1) * BIL_TYPE_SIZE + n;
     63  1.1  mrg     }
     64  1.1  mrg   /* Number of bits in (_BitInt(2048)) 9999999e+90DF.  */
     65  1.1  mrg   if (aiprec > 323 + (iprec < 0))
     66  1.1  mrg     {
     67  1.1  mrg     ovf:
     68  1.1  mrg       if (iprec < 0)
     69  1.1  mrg 	u.d = -9000000e+90DF;
     70  1.1  mrg       else
     71  1.1  mrg 	u.d = 9000000e+90DF;
     72  1.1  mrg       __asm ("" : "+g" (u.d));
     73  1.1  mrg       u.d += u.d;
     74  1.1  mrg       __asm ("" : "+g" (u.d));
     75  1.1  mrg       goto done;
     76  1.1  mrg     }
     77  1.1  mrg   /* Bit precision of 9999999uwb.  */
     78  1.1  mrg   if (aiprec >= 24)
     79  1.1  mrg     {
     80  1.1  mrg       USItype pow10_limbs, q_limbs, q2_limbs, j;
     81  1.1  mrg       USItype exp_bits = 0, e;
     82  1.1  mrg       UDItype m;
     83  1.1  mrg       UBILtype *buf;
     84  1.1  mrg       /* First do a possibly large divide smaller enough such that
     85  1.1  mrg 	 we only need to check remainder for 0 or non-0 and then
     86  1.1  mrg 	 we'll do further division.  */
     87  1.1  mrg       if (aiprec >= 24 + 4 + 10)
     88  1.1  mrg 	{
     89  1.1  mrg 	  exp_bits = (aiprec - 24 - 4) / 10;
     90  1.1  mrg 	  exponent = exp_bits * 3;
     91  1.1  mrg 	  /* Upper estimate for pow10 (exponent) bits.  */
     92  1.1  mrg 	  exp_bits = exp_bits * 10 - exp_bits / 30;
     93  1.1  mrg 	}
     94  1.1  mrg       pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
     95  1.1  mrg       /* 38 is the highest number of quotient bits needed on
     96  1.1  mrg 	 aiprec range of [38, 323].  E.g. if aiprec is 317,
     97  1.1  mrg 	 exponent will be 84 and exp_bits 280.  317 - 280 + 1
     98  1.1  mrg 	 is 38.  */
     99  1.1  mrg       q_limbs = (38 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
    100  1.1  mrg       q2_limbs = (32 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
    101  1.1  mrg       buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2)
    102  1.1  mrg 			      * sizeof (UBILtype));
    103  1.1  mrg       if (exponent)
    104  1.1  mrg 	{
    105  1.1  mrg 	  __bid_pow10bitint (buf + q_limbs, exp_bits, exponent);
    106  1.1  mrg 	  __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE,
    107  1.1  mrg 			   buf + q_limbs + pow10_limbs,
    108  1.1  mrg 			   pow10_limbs * BIL_TYPE_SIZE,
    109  1.1  mrg 			   i, iprec < 0 ? -aiprec : aiprec,
    110  1.1  mrg 			   buf + q_limbs, exp_bits);
    111  1.1  mrg 	  if (iprec < 0)
    112  1.1  mrg 	    bitint_negate (buf + BITINT_END (q_limbs - 1, 0),
    113  1.1  mrg 			   buf + BITINT_END (q_limbs - 1, 0), q_limbs);
    114  1.1  mrg 	  inexact = buf[q_limbs + pow10_limbs];
    115  1.1  mrg 	  for (j = 1; j < pow10_limbs; ++j)
    116  1.1  mrg 	    inexact |= buf[q_limbs + pow10_limbs + j];
    117  1.1  mrg 	}
    118  1.1  mrg       else
    119  1.1  mrg 	{
    120  1.1  mrg 	  __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), i,
    121  1.1  mrg 			    (in - 1) * sizeof (UBILtype));
    122  1.1  mrg 	  buf[BITINT_END (q_limbs - in, in - 1)] = msb;
    123  1.1  mrg 	  if (iprec < 0)
    124  1.1  mrg 	    bitint_negate (buf + BITINT_END (q_limbs - 1, 0),
    125  1.1  mrg 			   buf + BITINT_END (q_limbs - 1, 0), in);
    126  1.1  mrg 	  if (q_limbs > in)
    127  1.1  mrg 	    __builtin_memset (buf + BITINT_END (0, in), '\0',
    128  1.1  mrg 			      (q_limbs - in) * sizeof (UBILtype));
    129  1.1  mrg 	}
    130  1.1  mrg       e = 0;
    131  1.1  mrg #if BIL_TYPE_SIZE == 64
    132  1.1  mrg       m = buf[0];
    133  1.1  mrg #elif BIL_TYPE_SIZE == 32
    134  1.1  mrg       m = ((UDItype) buf[BITINT_END (0, 1)] << 32) | buf[BITINT_END (1, 0)];
    135  1.1  mrg #else
    136  1.1  mrg # error Unsupported BIL_TYPE_SIZE
    137  1.1  mrg #endif
    138  1.1  mrg       if (m >= (UDItype) 10000000000)
    139  1.1  mrg 	{
    140  1.1  mrg 	  if (m >= (UDItype) 100000000000)
    141  1.1  mrg 	    e = 5;
    142  1.1  mrg 	  else
    143  1.1  mrg 	    e = 4;
    144  1.1  mrg 	}
    145  1.1  mrg       else if (m >= (UDItype) 100000000)
    146  1.1  mrg 	{
    147  1.1  mrg 	  if (m >= (UDItype) 1000000000)
    148  1.1  mrg 	    e = 3;
    149  1.1  mrg 	  else
    150  1.1  mrg 	    e = 2;
    151  1.1  mrg 	}
    152  1.1  mrg       else if (m >= (UDItype) 10000000)
    153  1.1  mrg 	e = 1;
    154  1.1  mrg       exponent += e;
    155  1.1  mrg       if (exponent > 90)
    156  1.1  mrg 	goto ovf;
    157  1.1  mrg       if (e)
    158  1.1  mrg 	{
    159  1.1  mrg 	  UBILtype rem, half;
    160  1.1  mrg 	  __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2,
    161  1.1  mrg 			     BIL_TYPE_SIZE, e);
    162  1.1  mrg 	  __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1,
    163  1.1  mrg 			   q2_limbs * BIL_TYPE_SIZE,
    164  1.1  mrg 			   buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs,
    165  1.1  mrg 			   BIL_TYPE_SIZE,
    166  1.1  mrg 			   buf, q_limbs * BIL_TYPE_SIZE,
    167  1.1  mrg 			   buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE);
    168  1.1  mrg 	  half = buf[q_limbs + pow10_limbs * 2] / 2;
    169  1.1  mrg 	  rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs];
    170  1.1  mrg 	  if (inexact)
    171  1.1  mrg 	    {
    172  1.1  mrg 	      /* If first division discovered some non-0 digits
    173  1.1  mrg 		 and this second division is by 10, e.g.
    174  1.1  mrg 		 for XXXXXX5499999999999 or XXXXXX5000000000001
    175  1.1  mrg 		 if first division is by 10^12 and second by 10^1,
    176  1.1  mrg 		 doing rem |= 1 wouldn't change the 5.  Similarly
    177  1.1  mrg 		 for rem 4 doing rem |= 1 would change it to 5,
    178  1.1  mrg 		 but we don't want to change it in that case.  */
    179  1.1  mrg 	      if (e == 1)
    180  1.1  mrg 		{
    181  1.1  mrg 		  if (rem == 5)
    182  1.1  mrg 		    rem = 6;
    183  1.1  mrg 		  else if (rem != 4)
    184  1.1  mrg 		    rem |= 1;
    185  1.1  mrg 		}
    186  1.1  mrg 	      else
    187  1.1  mrg 		rem |= 1;
    188  1.1  mrg 	    }
    189  1.1  mrg 	  /* Set inexact to 0, 1, 2, 3 depending on if remainder
    190  1.1  mrg 	     of the divisions is exact 0, smaller than 10^exponent / 2,
    191  1.1  mrg 	     exactly 10^exponent / 2 or greater than that.  */
    192  1.1  mrg 	  if (rem >= half)
    193  1.1  mrg 	    inexact = 2 + (rem > half);
    194  1.1  mrg 	  else
    195  1.1  mrg 	    inexact = (rem != 0);
    196  1.1  mrg 	  mantissa = buf[q_limbs + pow10_limbs * 2 + 1];
    197  1.1  mrg 	}
    198  1.1  mrg       else
    199  1.1  mrg #if BIL_TYPE_SIZE == 64
    200  1.1  mrg 	mantissa = buf[0];
    201  1.1  mrg #else
    202  1.1  mrg 	mantissa = buf[BITINT_END (1, 0)];
    203  1.1  mrg #endif
    204  1.1  mrg     }
    205  1.1  mrg   else
    206  1.1  mrg     {
    207  1.1  mrg       mantissa = msb;
    208  1.1  mrg       if (iprec < 0)
    209  1.1  mrg 	mantissa = -mantissa;
    210  1.1  mrg     }
    211  1.1  mrg 
    212  1.1  mrg   exponent += 101;
    213  1.1  mrg   if (mantissa >= (USItype) 0x800000)
    214  1.1  mrg     u.u = (((((iprec < 0) << 2) | (USItype) 3) << 29)
    215  1.1  mrg 	   | (((USItype) exponent) << 21)
    216  1.1  mrg 	   | (mantissa ^ (USItype) 0x800000));
    217  1.1  mrg   else
    218  1.1  mrg     u.u = ((((USItype) (iprec < 0)) << 31)
    219  1.1  mrg 	   | (((USItype) exponent) << 23)
    220  1.1  mrg 	   | mantissa);
    221  1.1  mrg   if (inexact)
    222  1.1  mrg     {
    223  1.1  mrg       ui.u = ((((USItype) (iprec < 0)) << 31)
    224  1.1  mrg 	      | (((USItype) (exponent - 1)) << 23)
    225  1.1  mrg 	      | (inexact + 3));
    226  1.1  mrg       __asm ("" : "+g" (u.d));
    227  1.1  mrg       __asm ("" : "+g" (ui.d));
    228  1.1  mrg       u.d += ui.d;
    229  1.1  mrg       __asm ("" : "+g" (u.d));
    230  1.1  mrg     }
    231  1.1  mrg 
    232  1.1  mrg done:
    233  1.1  mrg   return u.d;
    234  1.1  mrg }
    235  1.1  mrg #endif
    236