/* d-longdouble.cc -- Software floating-point emulation for the frontend.
   Copyright (C) 2006-2021 Free Software Foundation, Inc.

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.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"

#include "dmd/mtype.h"

#include "tree.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "stor-layout.h"

#include "d-tree.h"
#include "longdouble.h"


/* Constant real values 0, 1, -1 and 0.5.  */
real_t CTFloat::zero;
real_t CTFloat::one;
real_t CTFloat::minusone;
real_t CTFloat::half;

/* Truncate longdouble to the highest precision supported by target.  */

longdouble
longdouble::normalize (void)
{
  const machine_mode mode = TYPE_MODE (long_double_type_node);
  real_convert (&this->rv (), mode, &this->rv ());
  return *this;
}

/* Assign a real_value to a longdouble type.  */

void
longdouble::set (real_value &d)
{
  real_convert (&this->rv (), TYPE_MODE (long_double_type_node), &d);
}

/* Conversion routines between longdouble and integer types.  */

void
longdouble::set (int32_t d)
{
  real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, SIGNED);
}

void
longdouble::set (int64_t d)
{
  real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,
		     SIGNED);
}

int64_t
longdouble::to_int (void) const
{
  bool overflow;
  wide_int wi = real_to_integer (&this->rv (), &overflow, 64);
  return wi.to_shwi ();
}

/* Unsigned variants of the same conversion routines.  */

void
longdouble::set (uint32_t d)
{
  real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, UNSIGNED);
}

void
longdouble::set (uint64_t d)
{
  real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,
		     UNSIGNED);
}

uint64_t
longdouble::to_uint (void) const
{
  bool overflow;
  wide_int wi = real_to_integer (&this->rv (), &overflow, 64);
  return wi.to_uhwi ();
}

/* For conversion between boolean, only need to check if is zero.  */

void
longdouble::set (bool d)
{
  this->rv () = (d == false) ? dconst0 : dconst1;
}

bool
longdouble::to_bool (void) const
{
  return this->rv ().cl != rvc_zero;
}

/* Overload numeric operators for longdouble types.  */

longdouble
longdouble::add (const longdouble &r) const
{
  longdouble x;
  real_arithmetic (&x.rv (), PLUS_EXPR, &this->rv (), &r.rv ());
  return x.normalize ();
}

longdouble
longdouble::sub (const longdouble &r) const
{
  longdouble x;
  real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &r.rv ());
  return x.normalize ();
}

longdouble
longdouble::mul (const longdouble &r) const
{
  longdouble x;
  real_arithmetic (&x.rv (), MULT_EXPR, &this->rv (), &r.rv ());
  return x.normalize ();
}

longdouble
longdouble::div (const longdouble &r) const
{
  longdouble x;
  real_arithmetic (&x.rv (), RDIV_EXPR, &this->rv (), &r.rv ());
  return x.normalize ();
}

longdouble
longdouble::mod (const longdouble &r) const
{
  longdouble x;
  real_value q;

  if (r.rv ().cl == rvc_zero || REAL_VALUE_ISINF (this->rv ()))
    {
      real_nan (&x.rv (), "", 1, TYPE_MODE (long_double_type_node));
      return x;
    }

  if (this->rv ().cl == rvc_zero)
    return *this;

  if (REAL_VALUE_ISINF (r.rv ()))
    return *this;

  /* Need to check for NaN?  */
  real_arithmetic (&q, RDIV_EXPR, &this->rv (), &r.rv ());
  real_arithmetic (&q, FIX_TRUNC_EXPR, &q, NULL);
  real_arithmetic (&q, MULT_EXPR, &q, &r.rv ());
  real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &q);

  return x.normalize ();
}

longdouble
longdouble::neg (void) const
{
  longdouble x;
  real_arithmetic (&x.rv (), NEGATE_EXPR, &this->rv (), NULL);
  return x.normalize ();
}

/* Overload equality operators for longdouble types.  */

int
longdouble::cmp (const longdouble &r) const
{
  if (real_compare (LT_EXPR, &this->rv (), &r.rv ()))
    return -1;

  if (real_compare (GT_EXPR, &this->rv (), &r.rv ()))
    return 1;

  return 0;
}

int
longdouble::equals (const longdouble &r) const
{
  return real_compare (EQ_EXPR, &this->rv (), &r.rv ());
}
