/* 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 decimal128FromString __dpd128FromString
#define decimal128ToString __dpd128ToString
#define decimal128ToEngString __dpd128ToEngString
#define decimal128FromNumber __dpd128FromNumber
#define decimal128ToNumber __dpd128ToNumber

#include "dpd/decimal128.c"

#undef decimal128FromString
#undef decimal128ToString
#undef decimal128ToEngString
#undef decimal128FromNumber
#undef decimal128ToNumber

#include "bid-dpd.h"

#ifdef IN_LIBGCC2
#define decimal128FromString __decimal128FromString
#define decimal128ToString __decimal128ToString
#define decimal128ToEngString __decimal128ToEngString
#define decimal128FromNumber __decimal128FromNumber
#define decimal128ToNumber __decimal128ToNumber
#endif

decimal128 *decimal128FromString (decimal128 *, const char *, decContext *);
char *decimal128ToString (const decimal128 *, char *);
char *decimal128ToEngString (const decimal128 *, char *);
decimal128 *decimal128FromNumber (decimal128 *, const decNumber *, decContext *);
decNumber *decimal128ToNumber (const decimal128 *, decNumber *);

void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);

decimal128 *
decimal128FromNumber (decimal128 *d128, const decNumber *dn,
		      decContext *set)
{
  /* decimal128 and _Decimal128 are different types.  */
  union
    {
      _Decimal128 _Dec;
      decimal128 dec;
    } u;

  __dpd128FromNumber (d128, dn, set);

  /* __dpd128FromNumber returns in big endian. But _dpd_to_bid128 takes
     host endian. */
  __ieee_to_host_128 (*d128, &u._Dec);

  /* Convert DPD to BID.  */
  _dpd_to_bid128 (&u._Dec, &u._Dec);

  /* dfp.c is in bid endian. */
  __host_to_ieee_128 (u._Dec, &u.dec);

  /* d128 is returned as a pointer to _Decimal128 here.  */
  *d128 = u.dec;

  return d128;
}

decNumber *
decimal128ToNumber (const decimal128 *bid128, decNumber *dn)
{
  /* decimal128 and _Decimal128 are different types.  */
  union
    {
      _Decimal128 _Dec;
      decimal128 dec;
    } u;

  /* bid128 is a pointer to _Decimal128 in bid endian. But _bid_to_dpd128
     takes host endian.  */
  __ieee_to_host_128 (*bid128, &u._Dec);

  /* Convert BID to DPD.  */
  _bid_to_dpd128 (&u._Dec, &u._Dec);

  /* __dpd128ToNumber is in bid endian.  */
  __host_to_ieee_128 (u._Dec, &u.dec);

  return __dpd128ToNumber (&u.dec, dn);
}

char *
decimal128ToString (const decimal128 *d128, char *string)
{
  decNumber dn;			/* work */
  decimal128ToNumber (d128, &dn);
  decNumberToString (&dn, string);
  return string;
}

char *
decimal128ToEngString (const decimal128 *d128, char *string)
{
  decNumber dn;			/* work */
  decimal128ToNumber (d128, &dn);
  decNumberToEngString (&dn, string);
  return string;
}

decimal128 *
decimal128FromString (decimal128 *result, const char *string,
		      decContext *set)
{
  decContext dc;		/* work */
  decNumber dn;			/* .. */

  decContextDefault (&dc, DEC_INIT_DECIMAL128);	/* no traps, please */
  dc.round = set->round;	/* use supplied rounding */

  decNumberFromString (&dn, string, &dc);	/* will round if needed */
  decimal128FromNumber (result, &dn, &dc);
  if (dc.status != 0)
    {				/* something happened */
      decContextSetStatus (set, dc.status);	/* .. pass it on */
    }
  return result;
}
