119304Speter/* Operations with long integers.
219304Speter   Copyright (C) 2006 Free Software Foundation, Inc.
319304Speter
419304SpeterThis file is part of GCC.
519304Speter
619304SpeterGCC is free software; you can redistribute it and/or modify it
719304Speterunder the terms of the GNU General Public License as published by the
819304SpeterFree Software Foundation; either version 2, or (at your option) any
919304Speterlater version.
1019304Speter
1119304SpeterGCC is distributed in the hope that it will be useful, but WITHOUT
1219304SpeterANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1319304SpeterFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1419304Speterfor more details.
1519304Speter
1619304SpeterYou should have received a copy of the GNU General Public License
1719304Speteralong with GCC; see the file COPYING.  If not, write to the Free
1819304SpeterSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
1919304Speter02110-1301, USA.  */
2019304Speter
2119304Speter#ifndef DOUBLE_INT_H
2219304Speter#define DOUBLE_INT_H
2319304Speter
2419304Speter/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
2519304Speter   It therefore represents a number with precision of
2619304Speter   2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
2719304Speter   internal representation will change, if numbers with greater precision
2819304Speter   are needed, so the users should not rely on it).  The representation does
2919304Speter   not contain any information about signedness of the represented value, so
3019304Speter   it can be used to represent both signed and unsigned numbers.  For
3119304Speter   operations where the results depend on signedness (division, comparisons),
3219304Speter   it must be specified separately.  For each such operation, there are three
3319304Speter   versions of the function -- double_int_op, that takes an extra UNS argument
3419304Speter   giving the signedness of the values, and double_int_sop and double_int_uop
3519304Speter   that stand for its specializations for signed and unsigned values.
3619304Speter
3719304Speter   You may also represent with numbers in smaller precision using double_int.
3819304Speter   You however need to use double_int_ext (that fills in the bits of the
3919304Speter   number over the prescribed precision with zeros or with the sign bit) before
4019304Speter   operations that do not perform arithmetics modulo 2^precision (comparisons,
4119304Speter   division), and possibly before storing the results, if you want to keep
4219304Speter   them in some canonical form).  In general, the signedness of double_int_ext
4319304Speter   should match the signedness of the operation.
4419304Speter
4519304Speter   ??? The components of double_int differ in signedness mostly for
4619304Speter   historical reasons (they replace an older structure used to represent
4719304Speter   numbers with precision higher than HOST_WIDE_INT).  It might be less
4819304Speter   confusing to have them both signed or both unsigned.  */
4919304Speter
5019304Spetertypedef struct
5119304Speter{
5219304Speter  unsigned HOST_WIDE_INT low;
5319304Speter  HOST_WIDE_INT high;
5419304Speter} double_int;
5519304Speter
5619304Speterunion tree_node;
5719304Speter
5819304Speter/* Constructors and conversions.  */
5919304Speter
6019304Speterunion tree_node *double_int_to_tree (union tree_node *, double_int);
6119304Speterdouble_int tree_to_double_int (union tree_node *tree);
6219304Speter
6319304Speter/* Constructs double_int from integer CST.  The bits over the precision of
6419304Speter   HOST_WIDE_INT are filled with the sign bit.  */
6519304Speter
6619304Speterstatic inline double_int
6719304Spetershwi_to_double_int (HOST_WIDE_INT cst)
6819304Speter{
6919304Speter  double_int r;
7019304Speter
7119304Speter  r.low = (unsigned HOST_WIDE_INT) cst;
7219304Speter  r.high = cst < 0 ? -1 : 0;
7319304Speter
7419304Speter  return r;
7519304Speter}
7619304Speter
7719304Speter/* Some useful constants.  */
7819304Speter
7919304Speter#define double_int_minus_one (shwi_to_double_int (-1))
8019304Speter#define double_int_zero (shwi_to_double_int (0))
8119304Speter#define double_int_one (shwi_to_double_int (1))
8219304Speter#define double_int_two (shwi_to_double_int (2))
8319304Speter#define double_int_ten (shwi_to_double_int (10))
8419304Speter
8519304Speter/* Constructs double_int from unsigned integer CST.  The bits over the
8619304Speter   precision of HOST_WIDE_INT are filled with zeros.  */
8719304Speter
8819304Speterstatic inline double_int
8919304Speteruhwi_to_double_int (unsigned HOST_WIDE_INT cst)
9019304Speter{
9119304Speter  double_int r;
9219304Speter
9319304Speter  r.low = cst;
9419304Speter  r.high = 0;
9519304Speter
9619304Speter  return r;
9719304Speter}
9819304Speter
9919304Speter/* The following operations perform arithmetics modulo 2^precision,
10019304Speter   so you do not need to call double_int_ext between them, even if
10119304Speter   you are representing numbers with precision less than
10219304Speter   2 * HOST_BITS_PER_WIDE_INT bits.  */
10319304Speter
10419304Speterdouble_int double_int_mul (double_int, double_int);
10519304Speterdouble_int double_int_add (double_int, double_int);
10619304Speterdouble_int double_int_neg (double_int);
10719304Speter
10819304Speter/* You must ensure that double_int_ext is called on the operands
10919304Speter   of the following operations, if the precision of the numbers
11019304Speter   is less than 2 * HOST_BITS_PER_WIDE_INT bits.  */
11119304Speterbool double_int_fits_in_hwi_p (double_int, bool);
11219304Speterbool double_int_fits_in_shwi_p (double_int);
11319304Speterbool double_int_fits_in_uhwi_p (double_int);
11419304SpeterHOST_WIDE_INT double_int_to_shwi (double_int);
11519304Speterunsigned HOST_WIDE_INT double_int_to_uhwi (double_int);
11619304Speterdouble_int double_int_div (double_int, double_int, bool, unsigned);
11719304Speterdouble_int double_int_sdiv (double_int, double_int, unsigned);
11819304Speterdouble_int double_int_udiv (double_int, double_int, unsigned);
11919304Speterdouble_int double_int_mod (double_int, double_int, bool, unsigned);
12019304Speterdouble_int double_int_smod (double_int, double_int, unsigned);
12119304Speterdouble_int double_int_umod (double_int, double_int, unsigned);
12219304Speterdouble_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
12319304Speterdouble_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
12419304Speterdouble_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
12519304Speterbool double_int_negative_p (double_int);
12619304Speterint double_int_cmp (double_int, double_int, bool);
12719304Speterint double_int_scmp (double_int, double_int);
12819304Speterint double_int_ucmp (double_int, double_int);
12919304Spetervoid dump_double_int (FILE *, double_int, bool);
13019304Speter
13119304Speter/* Zero and sign extension of numbers in smaller precisions.  */
13219304Speter
13319304Speterdouble_int double_int_ext (double_int, unsigned, bool);
13419304Speterdouble_int double_int_sext (double_int, unsigned);
13519304Speterdouble_int double_int_zext (double_int, unsigned);
13619304Speter
13719304Speter#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
13819304Speter
13919304Speter/* The operands of the following comparison functions must be processed
14019304Speter   with double_int_ext, if their precision is less than
14119304Speter   2 * HOST_BITS_PER_WIDE_INT bits.  */
14219304Speter
14319304Speter/* Returns true if CST is zero.  */
14419304Speter
14519304Speterstatic inline bool
14619304Speterdouble_int_zero_p (double_int cst)
14719304Speter{
14819304Speter  return cst.low == 0 && cst.high == 0;
14919304Speter}
15019304Speter
15119304Speter/* Returns true if CST is one.  */
15219304Speter
15319304Speterstatic inline bool
15419304Speterdouble_int_one_p (double_int cst)
15519304Speter{
15619304Speter  return cst.low == 1 && cst.high == 0;
15719304Speter}
15819304Speter
15919304Speter/* Returns true if CST is minus one.  */
16019304Speter
16119304Speterstatic inline bool
16219304Speterdouble_int_minus_one_p (double_int cst)
16319304Speter{
16419304Speter  return (cst.low == ALL_ONES && cst.high == -1);
16519304Speter}
16619304Speter
16719304Speter/* Returns true if CST1 == CST2.  */
16819304Speter
16919304Speterstatic inline bool
17019304Speterdouble_int_equal_p (double_int cst1, double_int cst2)
17119304Speter{
17219304Speter  return cst1.low == cst2.low && cst1.high == cst2.high;
17319304Speter}
17419304Speter
17519304Speter#endif /* DOUBLE_INT_H */
17619304Speter