/* Software floating-point emulation.
   Convert _Decimal32 to signed or unsigned _BitInt.

   Copyright (C) 2023 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__
extern void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32);

void
__bid_fixsdbitint (UBILtype *r, SItype rprec, _Decimal32 a)
{
  FP_DECL_EX;
  USItype arprec = rprec < 0 ? -rprec : rprec;
  USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
  union { _Decimal32 d; USItype u; } u;
  USItype mantissa, t;
  SItype sgn;
  SItype exponent;
  USItype exp_bits, mant_bits;
  UBILtype *pow10v, *resv;
  USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros;

  FP_INIT_EXCEPTIONS;
  u.d = a;
  t = u.u >> 21;
  sgn = (SItype) u.u < 0;
  if ((t & (3 << 8)) != (3 << 8))
    {
      mantissa = u.u & ((((USItype) 1) << 23) - 1);
      exponent = (t >> 2) & 0xff;
    }
  else if ((t & (3 << 6)) != (3 << 6))
    {
      mantissa = u.u & ((((USItype) 1) << 21) - 1);
      mantissa |= ((USItype) 1) << 23;
      exponent = t & 0xff;
      if (mantissa > (USItype) 9999999)
	mantissa = 0;
    }
  else
    {
      FP_SET_EXCEPTION (FP_EX_INVALID
			| FP_EX_INVALID_CVI
			| ((FP_EX_INVALID_SNAN
			    && ((t & 0x20)) != 0)
			   ? FP_EX_INVALID_SNAN : 0));
    ovf:
      if (!sgn)
	__builtin_memset (r, -1, rn * sizeof (UBILtype));
      else
	__builtin_memset (r, 0, rn * sizeof (UBILtype));
      if (sgn ^ (rprec >= 0))
	r[BITINT_END (0, rn - 1)]
	  |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE);
      else
	r[BITINT_END (0, rn - 1)]
	  &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE));
      goto done;
    }
  exponent -= 101;

  if (mantissa == 0)
    {
      /* Zero (with any exponent).  */
    zero:
      __builtin_memset (r, 0, rn * sizeof (UBILtype));
      goto done;
    }
  if (exponent <= -7)
    {
      FP_SET_EXCEPTION (FP_EX_INEXACT);
      goto zero;
    }
  else if (exponent < 0)
    {
      UBILtype limbs[64 / BIL_TYPE_SIZE];
      USItype rem;
      UDItype d;
      __bid_pow10bitint (limbs, 64, -exponent);
#if BIL_TYPE_SIZE == 64
      d = limbs[0];
#elif BIL_TYPE_SIZE == 32
      d = (limbs[BITINT_END (0, 1)] << 32) | limbs[BITINT_END (1, 0)];
#else
# error Unsupported BIL_TYPE_SIZE
#endif
      rem = mantissa % (USItype) d;
      mantissa /= (USItype) d;
      if (rem)
	FP_SET_EXCEPTION (FP_EX_INEXACT);
      if (mantissa == 0)
	goto zero;
      exponent = 0;
    }

  if (rprec >= 0 && sgn)
    {
    ovf_ex:
      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);
      goto ovf;
    }

  /* Lower estimate for number of bits needed for pow10 (exponent).  */
  exp_bits = exponent / 3;
  exp_bits = exp_bits * 10 - exp_bits / 29;
  mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissa);
  if (exp_bits + mant_bits > arprec + 1)
    goto ovf_ex;
  /* Upper estimate for number of bits needed for pow10 (exponent).  */
  exp_bits = (exponent + 2) / 3;
  exp_bits = exp_bits * 10 - exp_bits / 30;
  if (exp_bits == 0)
    exp_bits = 1;
  pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
  pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype));
  low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent);

  res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1)
	       / BIL_TYPE_SIZE) - low_zeros;
  mant_limbs = 1;
  resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype));
  resv[res_limbs] = mantissa;
  __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE,
		resv + res_limbs, mant_bits,
		pow10v + BITINT_END (0, low_zeros),
		exp_bits - low_zeros * BIL_TYPE_SIZE);
  if (res_limbs + low_zeros >= rn)
    {
      if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)])
	goto ovf_ex;
      if ((arprec % BIL_TYPE_SIZE) != 0
	  && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros]
	      & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0)
	goto ovf_ex;
      min_limbs = rn - low_zeros;
    }
  else
    min_limbs = res_limbs;
  if (low_zeros)
    __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0',
		      low_zeros * sizeof (UBILtype));
  if (sgn)
    bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros),
		   resv + BITINT_END (res_limbs - 1, 0), min_limbs);
  else
    __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros),
		      resv + BITINT_END (res_limbs - min_limbs, 0),
		      min_limbs * sizeof (UBILtype));
  if (res_limbs + low_zeros < rn)
    {
      if (sgn)
	__builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1,
			  (rn - res_limbs - low_zeros) * sizeof (UBILtype));
      else
	__builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0',
			  (rn - res_limbs - low_zeros) * sizeof (UBILtype));
    }
  else if (sgn)
    {
      if ((r[BITINT_END (0, rn - 1)]
	   & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0)
	goto ovf_ex;
    }
  else if (rprec < 0
	   && (r[BITINT_END (0, rn - 1)]
	       & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0)
    goto ovf_ex;

done:
  FP_HANDLE_EXCEPTIONS;
}
#endif
