Home | History | Annotate | Line # | Download | only in soft-fp
      1  1.1  mrg /* Software floating-point emulation.
      2  1.1  mrg    Convert _Decimal32 to signed or unsigned _BitInt.
      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 void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32);
     32  1.1  mrg 
     33  1.1  mrg void
     34  1.1  mrg __bid_fixsdbitint (UBILtype *r, SItype rprec, _Decimal32 a)
     35  1.1  mrg {
     36  1.1  mrg   FP_DECL_EX;
     37  1.1  mrg   USItype arprec = rprec < 0 ? -rprec : rprec;
     38  1.1  mrg   USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
     39  1.1  mrg   union { _Decimal32 d; USItype u; } u;
     40  1.1  mrg   USItype mantissa, t;
     41  1.1  mrg   SItype sgn;
     42  1.1  mrg   SItype exponent;
     43  1.1  mrg   USItype exp_bits, mant_bits;
     44  1.1  mrg   UBILtype *pow10v, *resv;
     45  1.1  mrg   USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros;
     46  1.1  mrg 
     47  1.1  mrg   FP_INIT_EXCEPTIONS;
     48  1.1  mrg   u.d = a;
     49  1.1  mrg   t = u.u >> 21;
     50  1.1  mrg   sgn = (SItype) u.u < 0;
     51  1.1  mrg   if ((t & (3 << 8)) != (3 << 8))
     52  1.1  mrg     {
     53  1.1  mrg       mantissa = u.u & ((((USItype) 1) << 23) - 1);
     54  1.1  mrg       exponent = (t >> 2) & 0xff;
     55  1.1  mrg     }
     56  1.1  mrg   else if ((t & (3 << 6)) != (3 << 6))
     57  1.1  mrg     {
     58  1.1  mrg       mantissa = u.u & ((((USItype) 1) << 21) - 1);
     59  1.1  mrg       mantissa |= ((USItype) 1) << 23;
     60  1.1  mrg       exponent = t & 0xff;
     61  1.1  mrg       if (mantissa > (USItype) 9999999)
     62  1.1  mrg 	mantissa = 0;
     63  1.1  mrg     }
     64  1.1  mrg   else
     65  1.1  mrg     {
     66  1.1  mrg       FP_SET_EXCEPTION (FP_EX_INVALID
     67  1.1  mrg 			| FP_EX_INVALID_CVI
     68  1.1  mrg 			| ((FP_EX_INVALID_SNAN
     69  1.1  mrg 			    && ((t & 0x20)) != 0)
     70  1.1  mrg 			   ? FP_EX_INVALID_SNAN : 0));
     71  1.1  mrg     ovf:
     72  1.1  mrg       if (!sgn)
     73  1.1  mrg 	__builtin_memset (r, -1, rn * sizeof (UBILtype));
     74  1.1  mrg       else
     75  1.1  mrg 	__builtin_memset (r, 0, rn * sizeof (UBILtype));
     76  1.1  mrg       if (sgn ^ (rprec >= 0))
     77  1.1  mrg 	r[BITINT_END (0, rn - 1)]
     78  1.1  mrg 	  |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE);
     79  1.1  mrg       else
     80  1.1  mrg 	r[BITINT_END (0, rn - 1)]
     81  1.1  mrg 	  &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE));
     82  1.1  mrg       goto done;
     83  1.1  mrg     }
     84  1.1  mrg   exponent -= 101;
     85  1.1  mrg 
     86  1.1  mrg   if (mantissa == 0)
     87  1.1  mrg     {
     88  1.1  mrg       /* Zero (with any exponent).  */
     89  1.1  mrg     zero:
     90  1.1  mrg       __builtin_memset (r, 0, rn * sizeof (UBILtype));
     91  1.1  mrg       goto done;
     92  1.1  mrg     }
     93  1.1  mrg   if (exponent <= -7)
     94  1.1  mrg     {
     95  1.1  mrg       FP_SET_EXCEPTION (FP_EX_INEXACT);
     96  1.1  mrg       goto zero;
     97  1.1  mrg     }
     98  1.1  mrg   else if (exponent < 0)
     99  1.1  mrg     {
    100  1.1  mrg       UBILtype limbs[64 / BIL_TYPE_SIZE];
    101  1.1  mrg       USItype rem;
    102  1.1  mrg       UDItype d;
    103  1.1  mrg       __bid_pow10bitint (limbs, 64, -exponent);
    104  1.1  mrg #if BIL_TYPE_SIZE == 64
    105  1.1  mrg       d = limbs[0];
    106  1.1  mrg #elif BIL_TYPE_SIZE == 32
    107  1.1  mrg       d = (UDItype) limbs[BITINT_END (0, 1)] << 32 | limbs[BITINT_END (1, 0)];
    108  1.1  mrg #else
    109  1.1  mrg # error Unsupported BIL_TYPE_SIZE
    110  1.1  mrg #endif
    111  1.1  mrg       rem = mantissa % (USItype) d;
    112  1.1  mrg       mantissa /= (USItype) d;
    113  1.1  mrg       if (rem)
    114  1.1  mrg 	FP_SET_EXCEPTION (FP_EX_INEXACT);
    115  1.1  mrg       if (mantissa == 0)
    116  1.1  mrg 	goto zero;
    117  1.1  mrg       exponent = 0;
    118  1.1  mrg     }
    119  1.1  mrg 
    120  1.1  mrg   if (rprec >= 0 && sgn)
    121  1.1  mrg     {
    122  1.1  mrg     ovf_ex:
    123  1.1  mrg       FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);
    124  1.1  mrg       goto ovf;
    125  1.1  mrg     }
    126  1.1  mrg 
    127  1.1  mrg   /* Lower estimate for number of bits needed for pow10 (exponent).  */
    128  1.1  mrg   exp_bits = exponent / 3;
    129  1.1  mrg   exp_bits = exp_bits * 10 - exp_bits / 29;
    130  1.1  mrg   mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissa);
    131  1.1  mrg   if (exp_bits + mant_bits > arprec + 1)
    132  1.1  mrg     goto ovf_ex;
    133  1.1  mrg   /* Upper estimate for number of bits needed for pow10 (exponent).  */
    134  1.1  mrg   exp_bits = (exponent + 2) / 3;
    135  1.1  mrg   exp_bits = exp_bits * 10 - exp_bits / 30;
    136  1.1  mrg   if (exp_bits == 0)
    137  1.1  mrg     exp_bits = 1;
    138  1.1  mrg   pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
    139  1.1  mrg   pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype));
    140  1.1  mrg   low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent);
    141  1.1  mrg 
    142  1.1  mrg   res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1)
    143  1.1  mrg 	       / BIL_TYPE_SIZE) - low_zeros;
    144  1.1  mrg   mant_limbs = 1;
    145  1.1  mrg   resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype));
    146  1.1  mrg   resv[res_limbs] = mantissa;
    147  1.1  mrg   __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE,
    148  1.1  mrg 		resv + res_limbs, mant_bits,
    149  1.1  mrg 		pow10v + BITINT_END (0, low_zeros),
    150  1.1  mrg 		exp_bits - low_zeros * BIL_TYPE_SIZE);
    151  1.1  mrg   if (res_limbs + low_zeros >= rn)
    152  1.1  mrg     {
    153  1.1  mrg       if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)])
    154  1.1  mrg 	goto ovf_ex;
    155  1.1  mrg       if ((arprec % BIL_TYPE_SIZE) != 0
    156  1.1  mrg 	  && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros]
    157  1.1  mrg 	      & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0)
    158  1.1  mrg 	goto ovf_ex;
    159  1.1  mrg       min_limbs = rn - low_zeros;
    160  1.1  mrg     }
    161  1.1  mrg   else
    162  1.1  mrg     min_limbs = res_limbs;
    163  1.1  mrg   if (low_zeros)
    164  1.1  mrg     __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0',
    165  1.1  mrg 		      low_zeros * sizeof (UBILtype));
    166  1.1  mrg   if (sgn)
    167  1.1  mrg     bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros),
    168  1.1  mrg 		   resv + BITINT_END (res_limbs - 1, 0), min_limbs);
    169  1.1  mrg   else
    170  1.1  mrg     __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros),
    171  1.1  mrg 		      resv + BITINT_END (res_limbs - min_limbs, 0),
    172  1.1  mrg 		      min_limbs * sizeof (UBILtype));
    173  1.1  mrg   if (res_limbs + low_zeros < rn)
    174  1.1  mrg     {
    175  1.1  mrg       if (sgn)
    176  1.1  mrg 	__builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1,
    177  1.1  mrg 			  (rn - res_limbs - low_zeros) * sizeof (UBILtype));
    178  1.1  mrg       else
    179  1.1  mrg 	__builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0',
    180  1.1  mrg 			  (rn - res_limbs - low_zeros) * sizeof (UBILtype));
    181  1.1  mrg     }
    182  1.1  mrg   else if (sgn)
    183  1.1  mrg     {
    184  1.1  mrg       if ((r[BITINT_END (0, rn - 1)]
    185  1.1  mrg 	   & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0)
    186  1.1  mrg 	goto ovf_ex;
    187  1.1  mrg     }
    188  1.1  mrg   else if (rprec < 0
    189  1.1  mrg 	   && (r[BITINT_END (0, rn - 1)]
    190  1.1  mrg 	       & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0)
    191  1.1  mrg     goto ovf_ex;
    192  1.1  mrg 
    193  1.1  mrg done:
    194  1.1  mrg   FP_HANDLE_EXCEPTIONS;
    195  1.1  mrg }
    196  1.1  mrg #endif
    197