/* Software floating-point emulation.
   Convert _Decimal128 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_fixtdbitint (UBILtype *, SItype, _Decimal128);

void
__bid_fixtdbitint (UBILtype *r, SItype rprec, _Decimal128 a)
{
  FP_DECL_EX;
  USItype arprec = rprec < 0 ? -rprec : rprec;
  USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
  union { _Decimal128 d; UDItype u[2]; } u;
  UDItype mantissahi, mantissalo, 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;
  mantissahi = u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__];
  mantissalo = u.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__];
  t = mantissahi >> 47;
  sgn = (DItype) mantissahi < 0;
  if ((t & (3 << 14)) != (3 << 14))
    {
      mantissahi &= ((((UDItype) 1) << 49) - 1);
      exponent = (t >> 2) & 0x3fff;
      if (mantissahi > (UDItype) 0x1ed09bead87c0
	  || (mantissahi == (UDItype) 0x1ed09bead87c0
	      && mantissalo > (UDItype) 0x378d8e63ffffffff))
	{
	  mantissahi = 0;
	  mantissalo = 0;
	}
    }
  else if ((t & (3 << 12)) != (3 << 12))
    {
      mantissahi = 0;
      mantissalo = 0;
      exponent = t & 0x3fff;
    }
  else
    {
      FP_SET_EXCEPTION (FP_EX_INVALID
			| FP_EX_INVALID_CVI
			| ((FP_EX_INVALID_SNAN
			    && ((t & 0x800)) != 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 -= 6176;

  if (mantissahi == 0 && mantissalo == 0)
    {
      /* Zero (with any exponent).  */
    zero:
      __builtin_memset (r, 0, rn * sizeof (UBILtype));
      goto done;
    }
  if (exponent <= -34)
    {
      FP_SET_EXCEPTION (FP_EX_INEXACT);
      goto zero;
    }
  if (exponent < 0)
    {
      UBILtype limbs[4 * 128 / BIL_TYPE_SIZE];
#if BIL_TYPE_SIZE == 64
      limbs[BITINT_END (0, 1)] = mantissahi;
      limbs[BITINT_END (1, 0)] = mantissalo;
#elif BIL_TYPE_SIZE == 32
      limbs[BITINT_END (0, 3)] = mantissahi >> 32;
      limbs[BITINT_END (1, 2)] = mantissahi;
      limbs[BITINT_END (2, 1)] = mantissalo >> 32;
      limbs[BITINT_END (3, 0)] = mantissalo;
#elif
# error Unhandled BIL_TYPE_SIZE
#endif
      __bid_pow10bitint (&limbs[128 / BIL_TYPE_SIZE], 128, -exponent);
      __divmodbitint4 (&limbs[2 * 128 / BIL_TYPE_SIZE], 128,
		       &limbs[3 * 128 / BIL_TYPE_SIZE], 128,
		       &limbs[0], 128, &limbs[128 / BIL_TYPE_SIZE], 128);
      UDItype rem;
#if BIL_TYPE_SIZE == 64
      mantissahi = limbs[BITINT_END (4, 5)];
      mantissalo = limbs[BITINT_END (5, 4)];
      rem = limbs[6] | limbs[7];
#elif BIL_TYPE_SIZE == 32
      mantissahi = limbs[BITINT_END (8, 11)] << 32;
      mantissahi |= limbs[BITINT_END (9, 10)];
      mantissalo = limbs[BITINT_END (10, 9)] << 32;
      mantissalo |= limbs[BITINT_END (11, 8)];
      rem = limbs[12] | limbs[13] | limbs[14] | limbs[15];
#endif
      if (rem)
	FP_SET_EXCEPTION (FP_EX_INEXACT);
      if (mantissahi == 0 && mantissalo == 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;
  if (mantissahi)
    mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissahi)
		+ 64;
  else
    mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissalo);
  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 = (mant_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
  resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype));
#if BIL_TYPE_SIZE >= 64
  if (mant_limbs == 1)
    resv[res_limbs] = mantissalo;
  else
    {
      resv[res_limbs + BITINT_END (1, 0)] = mantissalo;
      resv[res_limbs + BITINT_END (0, 1)] = mantissahi;
    }
#else
  resv[res_limbs + BITINT_END (mant_limbs - 1, 0)] = mantissalo;
  if (mant_limbs >= 2)
    {
      resv[res_limbs + BITINT_END (mant_limbs - 2, 1)] = mantissalo >> 32;
      if (mant_limbs >= 3)
	{
	  resv[res_limbs + BITINT_END (mant_limbs - 3, 2)] = mantissahi;
	  if (mant_limbs == 4)
	    resv[res_limbs + BITINT_END (0, 3)] = mantissahi >> 32;
	}
    }
#endif
  __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
