/* Copyright (C) 2007-2021 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/>.  */

#define BID_128RES
#include "bid_internal.h"

/*
 * Takes a BID64 as input and converts it to a BID128 and returns it. 
 */
TYPE0_FUNCTION_ARGTYPE1_NORND (UINT128, bid64_to_bid128, UINT64, x)

     UINT128 new_coeff, res;
     UINT64 sign_x;
     int exponent_x;
     UINT64 coefficient_x;

if (!unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x)) {
if (((x) << 1) >= 0xf000000000000000ull) {
#ifdef SET_STATUS_FLAGS
  if (((x) & SNAN_MASK64) == SNAN_MASK64)	// sNaN
    __set_status_flags (pfpsf, INVALID_EXCEPTION);
#endif
  res.w[0] = (coefficient_x & 0x0003ffffffffffffull);
  __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]);
  res.w[1] |= ((coefficient_x) & 0xfc00000000000000ull);
  BID_RETURN (res);
}
}

new_coeff.w[0] = coefficient_x;
new_coeff.w[1] = 0;
get_BID128_very_fast (&res, sign_x,
		      exponent_x + DECIMAL_EXPONENT_BIAS_128 -
		      DECIMAL_EXPONENT_BIAS, new_coeff);
BID_RETURN (res);
}	// convert_bid64_to_bid128



/*
 * Takes a BID128 as input and converts it to a BID64 and returns it.
 */
#if DECIMAL_CALL_BY_REFERENCE

void
bid128_to_bid64 (UINT64 * pres,
		 UINT128 *
		 px _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
		 _EXC_INFO_PARAM) {
  UINT128 x = *px;
#else

UINT64
bid128_to_bid64 (UINT128 x _RND_MODE_PARAM _EXC_FLAGS_PARAM
		 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
#endif
  UINT128 CX, T128, TP128, Qh, Ql, Qh1, Stemp, Tmp, Tmp1, CX1;
  UINT64 sign_x, carry, cy, res;
  SINT64 D;
  int_float f64, fx;
  int exponent_x, extra_digits, amount, bin_expon_cx;
  unsigned rmode, status, uf_check = 0;

#if DECIMAL_CALL_BY_REFERENCE
#if !DECIMAL_GLOBAL_ROUNDING
  _IDEC_round rnd_mode = *prnd_mode;
#endif
#endif

  BID_SWAP128 (x);
  // unpack arguments, check for NaN or Infinity or 0
  if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
    if ((x.w[1] << 1) >= 0xf000000000000000ull) {
      Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
      Tmp.w[0] = CX.w[0];
      TP128 = reciprocals10_128[18];
      __mul_128x128_full (Qh, Ql, Tmp, TP128);
      amount = recip_scale[18];
      __shr_128 (Tmp, Qh, amount);
      res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
#ifdef SET_STATUS_FLAGS
      if ((x.w[1] & SNAN_MASK64) == SNAN_MASK64)	// sNaN
	__set_status_flags (pfpsf, INVALID_EXCEPTION);
#endif
      BID_RETURN_VAL (res);
    }
    exponent_x =
      exponent_x - DECIMAL_EXPONENT_BIAS_128 + DECIMAL_EXPONENT_BIAS;
    if (exponent_x < 0) {
      res = sign_x;
      BID_RETURN_VAL (res);
    }
    if (exponent_x > DECIMAL_MAX_EXPON_64)
      exponent_x = DECIMAL_MAX_EXPON_64;
    res = sign_x | (((UINT64) exponent_x) << 53);
    BID_RETURN_VAL (res);
  }

  if (CX.w[1] || (CX.w[0] >= 10000000000000000ull)) {
    // find number of digits in coefficient
    // 2^64
    f64.i = 0x5f800000;
    // fx ~ CX
    fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
    bin_expon_cx = ((fx.i >> 23) & 0xff) - 0x7f;
    extra_digits = estimate_decimal_digits[bin_expon_cx] - 16;
    // scale = 38-estimate_decimal_digits[bin_expon_cx];
    D = CX.w[1] - power10_index_binexp_128[bin_expon_cx].w[1];
    if (D > 0
	|| (!D
	    && CX.w[0] >= power10_index_binexp_128[bin_expon_cx].w[0]))
      extra_digits++;

    exponent_x += extra_digits;

#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
    rmode = rnd_mode;
    if (sign_x && (unsigned) (rmode - 1) < 2)
      rmode = 3 - rmode;
#else
    rmode = 0;
#endif
#else
    rmode = 0;
#endif
    if (exponent_x < DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS) {
      uf_check = 1;
      if (-extra_digits + exponent_x - DECIMAL_EXPONENT_BIAS_128 +
	  DECIMAL_EXPONENT_BIAS + 35 >= 0) {
	if (exponent_x ==
	    DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS - 1) {
	  T128 = round_const_table_128[rmode][extra_digits];
	  __add_carry_out (CX1.w[0], carry, T128.w[0], CX.w[0]);
	  CX1.w[1] = CX.w[1] + T128.w[1] + carry;
	  if (__unsigned_compare_ge_128
	      (CX1, power10_table_128[extra_digits + 16]))
	    uf_check = 0;
	}
	extra_digits =
	  extra_digits + DECIMAL_EXPONENT_BIAS_128 -
	  DECIMAL_EXPONENT_BIAS - exponent_x;
	exponent_x = DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS;
	//uf_check = 2;
      } else
	rmode = ROUNDING_TO_ZERO;
    }

    T128 = round_const_table_128[rmode][extra_digits];
    __add_carry_out (CX.w[0], carry, T128.w[0], CX.w[0]);
    CX.w[1] = CX.w[1] + T128.w[1] + carry;

    TP128 = reciprocals10_128[extra_digits];
    __mul_128x128_full (Qh, Ql, CX, TP128);
    amount = recip_scale[extra_digits];

    if (amount >= 64) {
      CX.w[0] = Qh.w[1] >> (amount - 64);
      CX.w[1] = 0;
    } else {
      __shr_128 (CX, Qh, amount);
    }

#ifndef IEEE_ROUND_NEAREST_TIES_AWAY
#ifndef IEEE_ROUND_NEAREST
    if (!(rmode))
#endif
      if (CX.w[0] & 1) {
	// check whether fractional part of initial_P/10^ed1 is exactly .5

	// get remainder
	__shl_128_long (Qh1, Qh, (128 - amount));

	if (!Qh1.w[1] && !Qh1.w[0]
	    && (Ql.w[1] < reciprocals10_128[extra_digits].w[1]
		|| (Ql.w[1] == reciprocals10_128[extra_digits].w[1]
		    && Ql.w[0] < reciprocals10_128[extra_digits].w[0]))) {
	  CX.w[0]--;
	}
      }
#endif

    {
      status = INEXACT_EXCEPTION;
      // get remainder
      __shl_128_long (Qh1, Qh, (128 - amount));

      switch (rmode) {
      case ROUNDING_TO_NEAREST:
      case ROUNDING_TIES_AWAY:
	// test whether fractional part is 0
	if (Qh1.w[1] == 0x8000000000000000ull && (!Qh1.w[0])
	    && (Ql.w[1] < reciprocals10_128[extra_digits].w[1]
		|| (Ql.w[1] == reciprocals10_128[extra_digits].w[1]
		    && Ql.w[0] < reciprocals10_128[extra_digits].w[0])))
	  status = EXACT_STATUS;
	break;
      case ROUNDING_DOWN:
      case ROUNDING_TO_ZERO:
	if ((!Qh1.w[1]) && (!Qh1.w[0])
	    && (Ql.w[1] < reciprocals10_128[extra_digits].w[1]
		|| (Ql.w[1] == reciprocals10_128[extra_digits].w[1]
		    && Ql.w[0] < reciprocals10_128[extra_digits].w[0])))
	  status = EXACT_STATUS;
	break;
      default:
	// round up
	__add_carry_out (Stemp.w[0], cy, Ql.w[0],
			 reciprocals10_128[extra_digits].w[0]);
	__add_carry_in_out (Stemp.w[1], carry, Ql.w[1],
			    reciprocals10_128[extra_digits].w[1], cy);
	__shr_128_long (Qh, Qh1, (128 - amount));
	Tmp.w[0] = 1;
	Tmp.w[1] = 0;
	__shl_128_long (Tmp1, Tmp, amount);
	Qh.w[0] += carry;
	if (Qh.w[0] < carry)
	  Qh.w[1]++;
	if (__unsigned_compare_ge_128 (Qh, Tmp1))
	  status = EXACT_STATUS;
      }

      if (status != EXACT_STATUS) {
	if (uf_check)
	  status |= UNDERFLOW_EXCEPTION;
#ifdef SET_STATUS_FLAGS
	__set_status_flags (pfpsf, status);
#endif
      }


    }

  }

  res =
    get_BID64 (sign_x,
	       exponent_x - DECIMAL_EXPONENT_BIAS_128 +
	       DECIMAL_EXPONENT_BIAS, CX.w[0], rnd_mode, pfpsf);
  BID_RETURN_VAL (res);

}
