/* Operations with long integers.
   Copyright (C) 2006-2015 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 DOUBLE_INT_H
#define DOUBLE_INT_H

#include "wide-int.h"

/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
   It therefore represents a number with precision of
   2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
   internal representation will change, if numbers with greater precision
   are needed, so the users should not rely on it).  The representation does
   not contain any information about signedness of the represented value, so
   it can be used to represent both signed and unsigned numbers.  For
   operations where the results depend on signedness (division, comparisons),
   it must be specified separately.  For each such operation, there are three
   versions of the function -- double_int_op, that takes an extra UNS argument
   giving the signedness of the values, and double_int_sop and double_int_uop
   that stand for its specializations for signed and unsigned values.

   You may also represent with numbers in smaller precision using double_int.
   You however need to use double_int_ext (that fills in the bits of the
   number over the prescribed precision with zeros or with the sign bit) before
   operations that do not perform arithmetics modulo 2^precision (comparisons,
   division), and possibly before storing the results, if you want to keep
   them in some canonical form).  In general, the signedness of double_int_ext
   should match the signedness of the operation.

   ??? The components of double_int differ in signedness mostly for
   historical reasons (they replace an older structure used to represent
   numbers with precision higher than HOST_WIDE_INT).  It might be less
   confusing to have them both signed or both unsigned.  */

struct double_int
{
  /* Normally, we would define constructors to create instances.
     Two things prevent us from doing so.
     First, defining a constructor makes the class non-POD in C++03,
     and we certainly want double_int to be a POD.
     Second, the GCC conding conventions prefer explicit conversion,
     and explicit conversion operators are not available until C++11.  */

  static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
  static double_int from_shwi (HOST_WIDE_INT cst);
  static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);

  /* Construct from a fuffer of length LEN.  BUFFER will be read according
     to byte endianess and word endianess.  */
  static double_int from_buffer (const unsigned char *buffer, int len);

  /* No copy assignment operator or destructor to keep the type a POD.  */

  /* There are some special value-creation static member functions.  */

  static double_int mask (unsigned prec);
  static double_int max_value (unsigned int prec, bool uns);
  static double_int min_value (unsigned int prec, bool uns);

  /* The following functions are mutating operations.  */

  double_int &operator ++ (); // prefix
  double_int &operator -- (); // prefix
  double_int &operator *= (double_int);
  double_int &operator += (double_int);
  double_int &operator -= (double_int);
  double_int &operator &= (double_int);
  double_int &operator ^= (double_int);
  double_int &operator |= (double_int);

  /* The following functions are non-mutating operations.  */

  /* Conversion functions.  */

  HOST_WIDE_INT to_shwi () const;
  unsigned HOST_WIDE_INT to_uhwi () const;

  /* Conversion query functions.  */

  bool fits_uhwi () const;
  bool fits_shwi () const;
  bool fits_hwi (bool uns) const;

  /* Attribute query functions.  */

  int trailing_zeros () const;
  int popcount () const;

  /* Arithmetic query operations.  */

  bool multiple_of (double_int, bool, double_int *) const;

  /* Arithmetic operation functions.  */

  /* The following operations perform arithmetics modulo 2^precision, so you
     do not need to call .ext between them, even if you are representing
     numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits.  */

  double_int set_bit (unsigned) const;
  double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
  double_int wide_mul_with_sign (double_int, bool unsigned_p,
				 double_int *higher, bool *overflow) const;
  double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
  double_int sub_with_overflow (double_int, bool *overflow) const;
  double_int neg_with_overflow (bool *overflow) const;

  double_int operator * (double_int) const;
  double_int operator + (double_int) const;
  double_int operator - (double_int) const;
  double_int operator - () const;
  double_int operator ~ () const;
  double_int operator & (double_int) const;
  double_int operator | (double_int) const;
  double_int operator ^ (double_int) const;
  double_int and_not (double_int) const;

  double_int lshift (HOST_WIDE_INT count) const;
  double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
  double_int rshift (HOST_WIDE_INT count) const;
  double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
  double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
  double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
  double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
  double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
  double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
  double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;

  /* You must ensure that double_int::ext is called on the operands
     of the following operations, if the precision of the numbers
     is less than HOST_BITS_PER_DOUBLE_INT bits.  */

  double_int div (double_int, bool, unsigned) const;
  double_int sdiv (double_int, unsigned) const;
  double_int udiv (double_int, unsigned) const;
  double_int mod (double_int, bool, unsigned) const;
  double_int smod (double_int, unsigned) const;
  double_int umod (double_int, unsigned) const;
  double_int divmod_with_overflow (double_int, bool, unsigned,
				   double_int *, bool *) const;
  double_int divmod (double_int, bool, unsigned, double_int *) const;
  double_int sdivmod (double_int, unsigned, double_int *) const;
  double_int udivmod (double_int, unsigned, double_int *) const;

  /* Precision control functions.  */

  double_int ext (unsigned prec, bool uns) const;
  double_int zext (unsigned prec) const;
  double_int sext (unsigned prec) const;

  /* Comparative functions.  */

  bool is_zero () const;
  bool is_one () const;
  bool is_minus_one () const;
  bool is_negative () const;

  int cmp (double_int b, bool uns) const;
  int ucmp (double_int b) const;
  int scmp (double_int b) const;

  bool ult (double_int b) const;
  bool ule (double_int b) const;
  bool ugt (double_int b) const;
  bool slt (double_int b) const;
  bool sle (double_int b) const;
  bool sgt (double_int b) const;

  double_int max (double_int b, bool uns);
  double_int smax (double_int b);
  double_int umax (double_int b);

  double_int min (double_int b, bool uns);
  double_int smin (double_int b);
  double_int umin (double_int b);

  bool operator == (double_int cst2) const;
  bool operator != (double_int cst2) const;

  /* Please migrate away from using these member variables publicly.  */

  unsigned HOST_WIDE_INT low;
  HOST_WIDE_INT high;

};

#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)

/* Constructors and conversions.  */

/* Constructs double_int from integer CST.  The bits over the precision of
   HOST_WIDE_INT are filled with the sign bit.  */

inline double_int
double_int::from_shwi (HOST_WIDE_INT cst)
{
  double_int r;
  r.low = (unsigned HOST_WIDE_INT) cst;
  r.high = cst < 0 ? -1 : 0;
  return r;
}

/* Some useful constants.  */
/* FIXME(crowl): Maybe remove after converting callers?
   The problem is that a named constant would not be as optimizable,
   while the functional syntax is more verbose.  */

#define double_int_minus_one (double_int::from_shwi (-1))
#define double_int_zero (double_int::from_shwi (0))
#define double_int_one (double_int::from_shwi (1))
#define double_int_two (double_int::from_shwi (2))
#define double_int_ten (double_int::from_shwi (10))

/* Constructs double_int from unsigned integer CST.  The bits over the
   precision of HOST_WIDE_INT are filled with zeros.  */

inline double_int
double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
{
  double_int r;
  r.low = cst;
  r.high = 0;
  return r;
}

inline double_int
double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
{
  double_int r;
  r.low = low;
  r.high = high;
  return r;
}

inline double_int &
double_int::operator ++ ()
{
  *this += double_int_one;
  return *this;
}

inline double_int &
double_int::operator -- ()
{
  *this -= double_int_one;
  return *this;
}

inline double_int &
double_int::operator &= (double_int b)
{
  *this = *this & b;
  return *this;
}

inline double_int &
double_int::operator ^= (double_int b)
{
  *this = *this ^ b;
  return *this;
}

inline double_int &
double_int::operator |= (double_int b)
{
  *this = *this | b;
  return *this;
}

/* Returns value of CST as a signed number.  CST must satisfy
   double_int::fits_signed.  */

inline HOST_WIDE_INT
double_int::to_shwi () const
{
  return (HOST_WIDE_INT) low;
}

/* Returns value of CST as an unsigned number.  CST must satisfy
   double_int::fits_unsigned.  */

inline unsigned HOST_WIDE_INT
double_int::to_uhwi () const
{
  return low;
}

/* Returns true if CST fits in unsigned HOST_WIDE_INT.  */

inline bool
double_int::fits_uhwi () const
{
  return high == 0;
}

/* Logical operations.  */

/* Returns ~A.  */

inline double_int
double_int::operator ~ () const
{
  double_int result;
  result.low = ~low;
  result.high = ~high;
  return result;
}

/* Returns A | B.  */

inline double_int
double_int::operator | (double_int b) const
{
  double_int result;
  result.low = low | b.low;
  result.high = high | b.high;
  return result;
}

/* Returns A & B.  */

inline double_int
double_int::operator & (double_int b) const
{
  double_int result;
  result.low = low & b.low;
  result.high = high & b.high;
  return result;
}

/* Returns A & ~B.  */

inline double_int
double_int::and_not (double_int b) const
{
  double_int result;
  result.low = low & ~b.low;
  result.high = high & ~b.high;
  return result;
}

/* Returns A ^ B.  */

inline double_int
double_int::operator ^ (double_int b) const
{
  double_int result;
  result.low = low ^ b.low;
  result.high = high ^ b.high;
  return result;
}

void dump_double_int (FILE *, double_int, bool);

#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))

/* The operands of the following comparison functions must be processed
   with double_int_ext, if their precision is less than
   HOST_BITS_PER_DOUBLE_INT bits.  */

/* Returns true if CST is zero.  */

inline bool
double_int::is_zero () const
{
  return low == 0 && high == 0;
}

/* Returns true if CST is one.  */

inline bool
double_int::is_one () const
{
  return low == 1 && high == 0;
}

/* Returns true if CST is minus one.  */

inline bool
double_int::is_minus_one () const
{
  return low == ALL_ONES && high == -1;
}

/* Returns true if CST is negative.  */

inline bool
double_int::is_negative () const
{
  return high < 0;
}

/* Returns true if CST1 == CST2.  */

inline bool
double_int::operator == (double_int cst2) const
{
  return low == cst2.low && high == cst2.high;
}

/* Returns true if CST1 != CST2.  */

inline bool
double_int::operator != (double_int cst2) const
{
  return low != cst2.low || high != cst2.high;
}

/* Return number of set bits of CST.  */

inline int
double_int::popcount () const
{
  return popcount_hwi (high) + popcount_hwi (low);
}


#ifndef GENERATOR_FILE
/* Conversion to and from GMP integer representations.  */

void mpz_set_double_int (mpz_t, double_int, bool);
double_int mpz_get_double_int (const_tree, mpz_t, bool);
#endif

namespace wi
{
  template <>
  struct int_traits <double_int>
  {
    static const enum precision_type precision_type = CONST_PRECISION;
    static const bool host_dependent_precision = true;
    static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT;
    static unsigned int get_precision (const double_int &);
    static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
				      const double_int &);
  };
}

inline unsigned int
wi::int_traits <double_int>::get_precision (const double_int &)
{
  return precision;
}

inline wi::storage_ref
wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p,
					const double_int &x)
{
  gcc_checking_assert (precision == p);
  scratch[0] = x.low;
  if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0))
    return wi::storage_ref (scratch, 1, precision);
  scratch[1] = x.high;
  return wi::storage_ref (scratch, 2, precision);
}

#endif /* DOUBLE_INT_H */
