/* Definitions for simple data type for real numbers.
   Copyright (C) 2002-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.

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/>.  */

#ifndef GCC_SREAL_H
#define GCC_SREAL_H

#define SREAL_PART_BITS 31

#define UINT64_BITS	64

#define SREAL_MIN_SIG ((int64_t) 1 << (SREAL_PART_BITS - 2))
#define SREAL_MAX_SIG (((int64_t) 1 << (SREAL_PART_BITS - 1)) - 1)
#define SREAL_MAX_EXP (INT_MAX / 4)

#define SREAL_BITS SREAL_PART_BITS

#define SREAL_SIGN(v) (v < 0 ? -1: 1)
#define SREAL_ABS(v) (v < 0 ? -v: v)

struct output_block;
class lto_input_block;

/* Structure for holding a simple real number.  */
class sreal
{
public:
  /* Construct an uninitialized sreal.  */
  sreal () : m_sig (-1), m_exp (-1) {}

  /* Construct a sreal.  */
  sreal (int64_t sig, int exp = 0)
  {
    normalize (sig, exp);
  }

  void dump (FILE *) const;
  int64_t to_int () const;
  double to_double () const;
  void stream_out (struct output_block *);
  static sreal stream_in (class lto_input_block *);
  sreal operator+ (const sreal &other) const;
  sreal operator- (const sreal &other) const;
  sreal operator* (const sreal &other) const;
  sreal operator/ (const sreal &other) const;

  bool operator< (const sreal &other) const
  {
    if (m_exp == other.m_exp)
      return m_sig < other.m_sig;
    else
    {
      bool negative = m_sig < 0;
      bool other_negative = other.m_sig < 0;

      if (negative != other_negative)
        return negative > other_negative;

      bool r = m_exp < other.m_exp;
      return negative ? !r : r;
    }
  }

  bool operator== (const sreal &other) const
  {
    return m_exp == other.m_exp && m_sig == other.m_sig;
  }

  sreal operator- () const
  {
    sreal tmp = *this;
    tmp.m_sig *= -1;

    return tmp;
  }

  sreal shift (int s) const
  {
    /* Zero needs no shifting.  */
    if (!m_sig)
      return *this;
    gcc_checking_assert (s <= SREAL_MAX_EXP);
    gcc_checking_assert (s >= -SREAL_MAX_EXP);

    /* Overflows/drop to 0 could be handled gracefully, but hopefully we do not
       need to do so.  */
    gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
    gcc_checking_assert (m_exp + s >= -SREAL_MAX_EXP);

    sreal tmp = *this;
    tmp.m_exp += s;

    return tmp;
  }

  /* Global minimum sreal can hold.  */
  inline static sreal min ()
  {
    sreal min;
    /* This never needs normalization.  */
    min.m_sig = -SREAL_MAX_SIG;
    min.m_exp = SREAL_MAX_EXP;
    return min;
  }

  /* Global minimum sreal can hold.  */
  inline static sreal max ()
  {
    sreal max;
    /* This never needs normalization.  */
    max.m_sig = SREAL_MAX_SIG;
    max.m_exp = SREAL_MAX_EXP;
    return max;
  }

private:
  inline void normalize (int64_t new_sig, signed int new_exp);
  inline void normalize_up (int64_t new_sig, signed int new_exp);
  inline void normalize_down (int64_t new_sig, signed int new_exp);
  void shift_right (int amount);
  static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
  static sreal signedless_minus (const sreal &a, const sreal &b, bool negative);

  int32_t m_sig;			/* Significant.  */
  signed int m_exp;			/* Exponent.  */
};

extern void debug (const sreal &ref);
extern void debug (const sreal *ptr);

inline sreal &operator+= (sreal &a, const sreal &b)
{
  return a = a + b;
}

inline sreal &operator-= (sreal &a, const sreal &b)
{
  return a = a - b;
}

inline sreal &operator/= (sreal &a, const sreal &b)
{
  return a = a / b;
}

inline sreal &operator*= (sreal &a, const sreal &b)
{
  return a = a  * b;
}

inline bool operator!= (const sreal &a, const sreal &b)
{
  return !(a == b);
}

inline bool operator> (const sreal &a, const sreal &b)
{
  return !(a == b || a < b);
}

inline bool operator<= (const sreal &a, const sreal &b)
{
  return a < b || a == b;
}

inline bool operator>= (const sreal &a, const sreal &b)
{
  return a == b || a > b;
}

inline sreal operator<< (const sreal &a, int exp)
{
  return a.shift (exp);
}

inline sreal operator>> (const sreal &a, int exp)
{
  return a.shift (-exp);
}

/* Make significant to be >= SREAL_MIN_SIG.

   Make this separate method so inliner can handle hot path better.  */

inline void
sreal::normalize_up (int64_t new_sig, signed int new_exp)
{
  unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
  int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);

  gcc_checking_assert (shift > 0);
  sig <<= shift;
  new_exp -= shift;
  gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);

  /* Check underflow.  */
  if (new_exp < -SREAL_MAX_EXP)
    {
      new_exp = -SREAL_MAX_EXP;
      sig = 0;
    }
  m_exp = new_exp;
  if (SREAL_SIGN (new_sig) == -1)
    m_sig = -sig;
  else
    m_sig = sig;
}

/* Make significant to be <= SREAL_MAX_SIG.

   Make this separate method so inliner can handle hot path better.  */

inline void
sreal::normalize_down (int64_t new_sig, signed int new_exp)
{
  int last_bit;
  unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
  int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;

  gcc_checking_assert (shift > 0);
  last_bit = (sig >> (shift-1)) & 1;
  sig >>= shift;
  new_exp += shift;
  gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);

  /* Round the number.  */
  sig += last_bit;
  if (sig > SREAL_MAX_SIG)
    {
      sig >>= 1;
      new_exp++;
    }

  /* Check overflow.  */
  if (new_exp > SREAL_MAX_EXP)
    {
      new_exp = SREAL_MAX_EXP;
      sig = SREAL_MAX_SIG;
    }
  m_exp = new_exp;
  if (SREAL_SIGN (new_sig) == -1)
    m_sig = -sig;
  else
    m_sig = sig;
}

/* Normalize *this; the hot path.  */

inline void
sreal::normalize (int64_t new_sig, signed int new_exp)
{
  unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);

  if (sig == 0)
    {
      m_sig = 0;
      m_exp = -SREAL_MAX_EXP;
    }
  else if (sig > SREAL_MAX_SIG)
    normalize_down (new_sig, new_exp);
  else if (sig < SREAL_MIN_SIG)
    normalize_up (new_sig, new_exp);
  else
    {
      m_sig = new_sig;
      m_exp = new_exp;
    }
}

#endif
