diff options
author | Dan Albert <danalbert@google.com> | 2016-02-24 13:48:45 -0800 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2016-02-24 13:51:18 -0800 |
commit | b9de1157289455b0ca26daff519d4a0ddcd1fa13 (patch) | |
tree | 4c56cc0a34b91f17033a40a455f26652304f7b8d /gcc-4.8.3/gcc/double-int.h | |
parent | 098157a754787181cfa10e71325832448ddcea98 (diff) | |
download | toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.tar.gz toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.tar.bz2 toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.zip |
Update 4.8.1 to 4.8.3.
My previous drop was the wrong version. The platform mingw is
currently using 4.8.3, not 4.8.1 (not sure how I got that wrong).
From ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.3/gcc-4.8.3.tar.bz2.
Bug: http://b/26523949
Change-Id: Id85f1bdcbbaf78c7d0b5a69e74c798a08f341c35
Diffstat (limited to 'gcc-4.8.3/gcc/double-int.h')
-rw-r--r-- | gcc-4.8.3/gcc/double-int.h | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/gcc-4.8.3/gcc/double-int.h b/gcc-4.8.3/gcc/double-int.h new file mode 100644 index 000000000..5c425a84a --- /dev/null +++ b/gcc-4.8.3/gcc/double-int.h @@ -0,0 +1,457 @@ +/* Operations with long integers. + Copyright (C) 2006-2013 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 + +/* 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, unsigned int prec, bool arith) 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 publically. */ + + 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; +} + +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 + +#endif /* DOUBLE_INT_H */ |