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