| /* Software floating-point emulation. | 
 |    Convert a _BitInt to _Decimal128. | 
 |  | 
 |    Copyright (C) 2023-2025 Free Software Foundation, Inc. | 
 |  | 
 | This file is part of GCC. | 
 |  | 
 | GCC is free software; you can redistribute it and/or modify it under | 
 | the terms of the GNU General Public License as published by the Free | 
 | Software Foundation; either version 3, or (at your option) any later | 
 | version. | 
 |  | 
 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 
 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
 | FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
 | for more details. | 
 |  | 
 | Under Section 7 of GPL version 3, you are granted additional | 
 | permissions described in the GCC Runtime Library Exception, version | 
 | 3.1, as published by the Free Software Foundation. | 
 |  | 
 | You should have received a copy of the GNU General Public License and | 
 | a copy of the GCC Runtime Library Exception along with this program; | 
 | see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
 | <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #include "soft-fp.h" | 
 | #include "bitint.h" | 
 |  | 
 | #ifdef __BITINT_MAXWIDTH__ | 
 | #ifndef ENABLE_DECIMAL_BID_FORMAT | 
 | #define __bid_floatbitinttd __dpd_floatbitinttd | 
 | #endif | 
 | extern _Decimal128 __bid_floatbitinttd (const UBILtype *, SItype); | 
 |  | 
 | _Decimal128 | 
 | __bid_floatbitinttd (const UBILtype *i, SItype iprec) | 
 | { | 
 |   iprec = bitint_reduce_prec (&i, iprec); | 
 |   USItype aiprec = iprec < 0 ? -iprec : iprec; | 
 |   USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; | 
 |   USItype idx = BITINT_END (0, in - 1); | 
 |   UBILtype msb = i[idx]; | 
 |   UDItype mantissahi, mantissalo; | 
 |   SItype exponent = 0; | 
 |   UBILtype inexact = 0; | 
 |   union { _Decimal128 d; UDItype u[2]; } u, ui; | 
 |   if (aiprec % BIL_TYPE_SIZE) | 
 |     { | 
 |       if (iprec > 0) | 
 | 	msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1; | 
 |       else | 
 | 	msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE); | 
 |     } | 
 |   if (iprec < 0) | 
 |     { | 
 |       SItype n; | 
 |       if (msb == ~(UBILtype) 0) | 
 | 	n = 1; | 
 |       else | 
 | 	n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb); | 
 |       aiprec = (in - 1) * BIL_TYPE_SIZE + n; | 
 |     } | 
 |   else if (msb == 0) | 
 |     aiprec = 1; | 
 |   else | 
 |     { | 
 |       SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb); | 
 |       aiprec = (in - 1) * BIL_TYPE_SIZE + n; | 
 |     } | 
 |   /* Number of bits in | 
 |      (_BitInt(32768)) 9999999999999999999999999999999999e+6111DL.  */ | 
 |   if (aiprec > 20414 + (iprec < 0)) | 
 |     { | 
 |     ovf: | 
 |       if (iprec < 0) | 
 | 	u.d = -9000000000000000000000000000000000e+6111DL; | 
 |       else | 
 | 	u.d = 9000000000000000000000000000000000e+6111DL; | 
 |       __asm ("" : "+g" (u.d)); | 
 |       u.d += u.d; | 
 |       __asm ("" : "+g" (u.d)); | 
 |       goto done; | 
 |     } | 
 |   /* Bit precision of 9999999999999999999999999999999999uwb.  */ | 
 |   if (aiprec >= 113) | 
 |     { | 
 |       USItype pow10_limbs, q_limbs, q2_limbs, j, k; | 
 |       USItype exp_bits = 0, e; | 
 |       UBILtype *buf; | 
 |       /* First do a possibly large divide smaller enough such that | 
 | 	 we only need to check remainder for 0 or non-0 and then | 
 | 	 we'll do further division.  */ | 
 |       if (aiprec >= 113 + 4 + 10) | 
 | 	{ | 
 | 	  exp_bits = ((aiprec - 113 - 4) * (UDItype) 30) / 299; | 
 | 	  exponent = exp_bits * 3; | 
 | 	  /* Upper estimate for pow10 (exponent) bits.  */ | 
 | 	  exp_bits = exp_bits * 10 - exp_bits / 30; | 
 | 	} | 
 |       pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; | 
 |       /* 127 is the highest number of quotient bits needed on | 
 | 	 aiprec range of [127, 20414].  E.g. if aiprec is 20409, | 
 | 	 exponent will be 6105 and exp_bits 20283.  20409 - 20283 + 1 | 
 | 	 is 127.  */ | 
 |       q_limbs = (127 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; | 
 |       q2_limbs = 128 / BIL_TYPE_SIZE; | 
 |       buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2) | 
 | 			      * sizeof (UBILtype)); | 
 |       if (exponent) | 
 | 	{ | 
 | 	  __bid_pow10bitint (buf + q_limbs, exp_bits, exponent); | 
 | 	  __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE, | 
 | 			   buf + q_limbs + pow10_limbs, | 
 | 			   pow10_limbs * BIL_TYPE_SIZE, | 
 | 			   i, iprec < 0 ? -aiprec : aiprec, | 
 | 			   buf + q_limbs, exp_bits); | 
 | 	  if (iprec < 0) | 
 | 	    bitint_negate (buf + BITINT_END (q_limbs - 1, 0), | 
 | 			   buf + BITINT_END (q_limbs - 1, 0), q_limbs); | 
 | 	  inexact = buf[q_limbs + pow10_limbs]; | 
 | 	  for (j = 1; j < pow10_limbs; ++j) | 
 | 	    inexact |= buf[q_limbs + pow10_limbs + j]; | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), | 
 | 			    i + BITINT_END (1, 0), | 
 | 			    (in - 1) * sizeof (UBILtype)); | 
 | 	  buf[BITINT_END (q_limbs - in, in - 1)] = msb; | 
 | 	  if (iprec < 0) | 
 | 	    bitint_negate (buf + BITINT_END (q_limbs - 1, 0), | 
 | 			   buf + BITINT_END (q_limbs - 1, 0), in); | 
 | 	  if (q_limbs > in) | 
 | 	    __builtin_memset (buf + BITINT_END (0, in), '\0', | 
 | 			      (q_limbs - in) * sizeof (UBILtype)); | 
 | 	} | 
 |       e = 0; | 
 |       for (j = 3; j; ) | 
 | 	{ | 
 | 	  USItype eprev = e; | 
 | 	  __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2 + 1, | 
 | 			     128, 33 + e + j); | 
 | 	  for (k = BITINT_END (0, q_limbs - 1); | 
 | 	       k != BITINT_END (q_limbs, (USItype) -1); k -= BITINT_INC) | 
 | 	    if (buf[k] > buf[q_limbs + pow10_limbs * 2 + 1 + k]) | 
 | 	      { | 
 | 		e += j; | 
 | 		break; | 
 | 	      } | 
 | 	    else if (buf[k] < buf[q_limbs + pow10_limbs * 2 + 1 + k]) | 
 | 	      break; | 
 | 	  if (k == BITINT_END (q_limbs, (USItype) -1)) | 
 | 	    e += j; | 
 | 	  if (j == 2 && e != eprev) | 
 | 	    break; | 
 | 	  else | 
 | 	    --j; | 
 | 	} | 
 |       exponent += e; | 
 |       if (exponent > 6111) | 
 | 	goto ovf; | 
 |       if (e) | 
 | 	{ | 
 | 	  UBILtype rem, half; | 
 | 	  __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2, | 
 | 			     BIL_TYPE_SIZE, e); | 
 | 	  __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1, | 
 | 			   q2_limbs * BIL_TYPE_SIZE, | 
 | 			   buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs, | 
 | 			   BIL_TYPE_SIZE, | 
 | 			   buf, q_limbs * BIL_TYPE_SIZE, | 
 | 			   buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE); | 
 | 	  half = buf[q_limbs + pow10_limbs * 2] / 2; | 
 | 	  rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs]; | 
 | 	  if (inexact) | 
 | 	    { | 
 | 	      /* If first division discovered some non-0 digits | 
 | 		 and this second division is by 10, e.g. | 
 | 		 for XXXXXX5499999999999 or XXXXXX5000000000001 | 
 | 		 if first division is by 10^12 and second by 10^1, | 
 | 		 doing rem |= 1 wouldn't change the 5.  Similarly | 
 | 		 for rem 4 doing rem |= 1 would change it to 5, | 
 | 		 but we don't want to change it in that case.  */ | 
 | 	      if (e == 1) | 
 | 		{ | 
 | 		  if (rem == 5) | 
 | 		    rem = 6; | 
 | 		  else if (rem != 4) | 
 | 		    rem |= 1; | 
 | 		} | 
 | 	      else | 
 | 		rem |= 1; | 
 | 	    } | 
 | 	  /* Set inexact to 0, 1, 2, 3 depending on if remainder | 
 | 	     of the divisions is exact 0, smaller than 10^exponent / 2, | 
 | 	     exactly 10^exponent / 2 or greater than that.  */ | 
 | 	  if (rem >= half) | 
 | 	    inexact = 2 + (rem > half); | 
 | 	  else | 
 | 	    inexact = (rem != 0); | 
 | #if BIL_TYPE_SIZE == 64 | 
 | 	  mantissahi = buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (0, 1)]; | 
 | 	  mantissalo = buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (1, 0)]; | 
 | #else | 
 | 	  mantissahi | 
 | 	    = ((UDItype) | 
 | 	       buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (0, 3)] << 32 | 
 | 	       | buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (1, 2)]); | 
 | 	  mantissalo | 
 | 	    = ((UDItype) | 
 | 	       buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (2, 1)] << 32 | 
 | 	       | buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (3, 0)]); | 
 | #endif | 
 | 	} | 
 |       else | 
 | 	{ | 
 | #if BIL_TYPE_SIZE == 64 | 
 | 	  mantissahi = buf[BITINT_END (0, 1)]; | 
 | 	  mantissalo = buf[BITINT_END (1, 0)]; | 
 | #else | 
 | 	  mantissahi = ((UDItype) buf[BITINT_END (0, 3)] << 32 | 
 | 			| buf[BITINT_END (1, 2)]); | 
 | 	  mantissalo = ((UDItype) buf[BITINT_END (2, 1)] << 32 | 
 | 			| buf[BITINT_END (3, 0)]); | 
 | #endif | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       mantissahi = iprec < 0 ? -1 : 0; | 
 | #if BIL_TYPE_SIZE == 64 | 
 |       if (in == 1) | 
 | 	mantissalo = msb; | 
 |       else | 
 | 	{ | 
 | 	  mantissahi = msb; | 
 | 	  mantissalo = i[BITINT_END (1, 0)]; | 
 | 	} | 
 | #else | 
 |       if (in <= 2) | 
 | 	{ | 
 | 	  if (in == 1) | 
 | 	    mantissalo = iprec < 0 ? (UDItype) (BILtype) msb : (UDItype) msb; | 
 | 	  else | 
 | 	    mantissalo = (UDItype) msb << 32 | i[BITINT_END (1, 0)]; | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  if (in == 3) | 
 | 	    mantissahi = iprec < 0 ? (UDItype) (BILtype) msb : (UDItype) msb; | 
 | 	  else | 
 | 	    mantissahi = (UDItype) msb << 32 | i[BITINT_END (1, 2)]; | 
 | 	  mantissalo = ((UDItype) i[BITINT_END (in - 2, 1)] << 32 | 
 | 			| i[BITINT_END (in - 1, 0)]); | 
 | 	} | 
 | #endif | 
 |       if (iprec < 0) | 
 | 	mantissahi | 
 | 	  = ~mantissahi + __builtin_add_overflow (~mantissalo, 1, &mantissalo); | 
 |     } | 
 |  | 
 |   exponent += 6176; | 
 | #ifdef ENABLE_DECIMAL_BID_FORMAT | 
 |   u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] | 
 |     = ((((UDItype) (iprec < 0)) << 63) | 
 |        | (((UDItype) exponent) << 49) | 
 |        | mantissahi); | 
 | #else | 
 | #ifdef __SIZEOF_INT128__ | 
 |   unsigned __int128 m = mantissahi; | 
 | #else | 
 |   unsigned _BitInt(128) m = mantissahi; | 
 | #endif | 
 |   m = (m << 64) | mantissalo; | 
 |   u.u[0] = m / 1000000000000000ULL; | 
 |   u.u[1] = m % 1000000000000000ULL; | 
 |   mantissalo = __dpd_b2dbitint[u.u[1] % 1000]; | 
 |   u.u[1] /= 1000; | 
 |   mantissalo |= ((UDItype) __dpd_b2dbitint[u.u[1] % 1000]) << 10; | 
 |   u.u[1] /= 1000; | 
 |   mantissalo |= ((UDItype) __dpd_b2dbitint[u.u[1] % 1000]) << 20; | 
 |   u.u[1] /= 1000; | 
 |   mantissalo |= ((UDItype) __dpd_b2dbitint[u.u[1] % 1000]) << 30; | 
 |   u.u[1] /= 1000; | 
 |   mantissalo |= ((UDItype) __dpd_b2dbitint[u.u[1] % 1000]) << 40; | 
 |   mantissalo |= ((UDItype) __dpd_b2dbitint[u.u[0] % 1000]) << 50; | 
 |   u.u[0] /= 1000; | 
 |   mantissahi = __dpd_b2dbitint[u.u[0] % 1000]; | 
 |   u.u[0] /= 1000; | 
 |   mantissalo |= mantissahi << 60; | 
 |   mantissahi >>= 4; | 
 |   mantissahi |= ((UDItype) __dpd_b2dbitint[u.u[0] % 1000]) << 6; | 
 |   u.u[0] /= 1000; | 
 |   mantissahi |= ((UDItype) __dpd_b2dbitint[u.u[0] % 1000]) << 16; | 
 |   u.u[0] /= 1000; | 
 |   mantissahi |= ((UDItype) __dpd_b2dbitint[u.u[0] % 1000]) << 26; | 
 |   u.u[0] /= 1000; | 
 |   mantissahi |= ((UDItype) __dpd_b2dbitint[u.u[0] % 1000]) << 36; | 
 |   u.u[0] /= 1000; | 
 |   if (u.u[0] >= 8) | 
 |     u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] | 
 |       = (((((iprec < 0) << 2) | (UDItype) 3) << 61) | 
 | 	 | (((UDItype) exponent & (3 << 12)) << 47) | 
 | 	 | ((u.u[0] & 1) << 58) | 
 | 	 | (((UDItype) exponent & 4095) << 46) | 
 | 	 | mantissahi); | 
 |   else | 
 |     u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] | 
 |       = ((((UDItype) (iprec < 0)) << 63) | 
 | 	 | (((UDItype) exponent & (3 << 12)) << 49) | 
 | 	 | (u.u[0] << 58) | 
 | 	 | (((UDItype) exponent & 4095) << 46) | 
 | 	 | mantissahi); | 
 | #endif | 
 |   u.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__] = mantissalo; | 
 |   if (inexact) | 
 |     { | 
 |       ui.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] | 
 | #ifdef ENABLE_DECIMAL_BID_FORMAT | 
 | 	= (((UDItype) (iprec < 0)) << 63) | (((UDItype) exponent - 1) << 49); | 
 | #else | 
 | 	= ((((UDItype) (iprec < 0)) << 63) | 
 | 	   | ((((UDItype) exponent - 1) & (3 << 12)) << 49) | 
 | 	   | ((((UDItype) exponent - 1) & 4095) << 46)); | 
 | #endif | 
 |       ui.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__] = inexact + 3; | 
 |       __asm ("" : "+g" (u.d)); | 
 |       __asm ("" : "+g" (ui.d)); | 
 |       u.d += ui.d; | 
 |       __asm ("" : "+g" (u.d)); | 
 |     } | 
 |  | 
 | done: | 
 |   return u.d; | 
 | } | 
 | #endif |