1169689Skan/* Operations with long integers.
2169689Skan   Copyright (C) 2006 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify it
7169689Skanunder the terms of the GNU General Public License as published by the
8169689SkanFree Software Foundation; either version 2, or (at your option) any
9169689Skanlater version.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT
12169689SkanANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14169689Skanfor more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19169689Skan02110-1301, USA.  */
20169689Skan
21169689Skan#ifndef DOUBLE_INT_H
22169689Skan#define DOUBLE_INT_H
23169689Skan
24169689Skan/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
25169689Skan   It therefore represents a number with precision of
26169689Skan   2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
27169689Skan   internal representation will change, if numbers with greater precision
28169689Skan   are needed, so the users should not rely on it).  The representation does
29169689Skan   not contain any information about signedness of the represented value, so
30169689Skan   it can be used to represent both signed and unsigned numbers.  For
31169689Skan   operations where the results depend on signedness (division, comparisons),
32169689Skan   it must be specified separately.  For each such operation, there are three
33169689Skan   versions of the function -- double_int_op, that takes an extra UNS argument
34169689Skan   giving the signedness of the values, and double_int_sop and double_int_uop
35169689Skan   that stand for its specializations for signed and unsigned values.
36169689Skan
37169689Skan   You may also represent with numbers in smaller precision using double_int.
38169689Skan   You however need to use double_int_ext (that fills in the bits of the
39169689Skan   number over the prescribed precision with zeros or with the sign bit) before
40169689Skan   operations that do not perform arithmetics modulo 2^precision (comparisons,
41169689Skan   division), and possibly before storing the results, if you want to keep
42169689Skan   them in some canonical form).  In general, the signedness of double_int_ext
43169689Skan   should match the signedness of the operation.
44169689Skan
45169689Skan   ??? The components of double_int differ in signedness mostly for
46169689Skan   historical reasons (they replace an older structure used to represent
47169689Skan   numbers with precision higher than HOST_WIDE_INT).  It might be less
48169689Skan   confusing to have them both signed or both unsigned.  */
49169689Skan
50169689Skantypedef struct
51169689Skan{
52169689Skan  unsigned HOST_WIDE_INT low;
53169689Skan  HOST_WIDE_INT high;
54169689Skan} double_int;
55169689Skan
56169689Skanunion tree_node;
57169689Skan
58169689Skan/* Constructors and conversions.  */
59169689Skan
60169689Skanunion tree_node *double_int_to_tree (union tree_node *, double_int);
61169689Skandouble_int tree_to_double_int (union tree_node *tree);
62169689Skan
63169689Skan/* Constructs double_int from integer CST.  The bits over the precision of
64169689Skan   HOST_WIDE_INT are filled with the sign bit.  */
65169689Skan
66169689Skanstatic inline double_int
67169689Skanshwi_to_double_int (HOST_WIDE_INT cst)
68169689Skan{
69169689Skan  double_int r;
70169689Skan
71169689Skan  r.low = (unsigned HOST_WIDE_INT) cst;
72169689Skan  r.high = cst < 0 ? -1 : 0;
73169689Skan
74169689Skan  return r;
75169689Skan}
76169689Skan
77169689Skan/* Some useful constants.  */
78169689Skan
79169689Skan#define double_int_minus_one (shwi_to_double_int (-1))
80169689Skan#define double_int_zero (shwi_to_double_int (0))
81169689Skan#define double_int_one (shwi_to_double_int (1))
82169689Skan#define double_int_two (shwi_to_double_int (2))
83169689Skan#define double_int_ten (shwi_to_double_int (10))
84169689Skan
85169689Skan/* Constructs double_int from unsigned integer CST.  The bits over the
86169689Skan   precision of HOST_WIDE_INT are filled with zeros.  */
87169689Skan
88169689Skanstatic inline double_int
89169689Skanuhwi_to_double_int (unsigned HOST_WIDE_INT cst)
90169689Skan{
91169689Skan  double_int r;
92169689Skan
93169689Skan  r.low = cst;
94169689Skan  r.high = 0;
95169689Skan
96169689Skan  return r;
97169689Skan}
98169689Skan
99169689Skan/* The following operations perform arithmetics modulo 2^precision,
100169689Skan   so you do not need to call double_int_ext between them, even if
101169689Skan   you are representing numbers with precision less than
102169689Skan   2 * HOST_BITS_PER_WIDE_INT bits.  */
103169689Skan
104169689Skandouble_int double_int_mul (double_int, double_int);
105169689Skandouble_int double_int_add (double_int, double_int);
106169689Skandouble_int double_int_neg (double_int);
107169689Skan
108169689Skan/* You must ensure that double_int_ext is called on the operands
109169689Skan   of the following operations, if the precision of the numbers
110169689Skan   is less than 2 * HOST_BITS_PER_WIDE_INT bits.  */
111169689Skanbool double_int_fits_in_hwi_p (double_int, bool);
112169689Skanbool double_int_fits_in_shwi_p (double_int);
113169689Skanbool double_int_fits_in_uhwi_p (double_int);
114169689SkanHOST_WIDE_INT double_int_to_shwi (double_int);
115169689Skanunsigned HOST_WIDE_INT double_int_to_uhwi (double_int);
116169689Skandouble_int double_int_div (double_int, double_int, bool, unsigned);
117169689Skandouble_int double_int_sdiv (double_int, double_int, unsigned);
118169689Skandouble_int double_int_udiv (double_int, double_int, unsigned);
119169689Skandouble_int double_int_mod (double_int, double_int, bool, unsigned);
120169689Skandouble_int double_int_smod (double_int, double_int, unsigned);
121169689Skandouble_int double_int_umod (double_int, double_int, unsigned);
122169689Skandouble_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
123169689Skandouble_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
124169689Skandouble_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
125169689Skanbool double_int_negative_p (double_int);
126169689Skanint double_int_cmp (double_int, double_int, bool);
127169689Skanint double_int_scmp (double_int, double_int);
128169689Skanint double_int_ucmp (double_int, double_int);
129169689Skanvoid dump_double_int (FILE *, double_int, bool);
130169689Skan
131169689Skan/* Zero and sign extension of numbers in smaller precisions.  */
132169689Skan
133169689Skandouble_int double_int_ext (double_int, unsigned, bool);
134169689Skandouble_int double_int_sext (double_int, unsigned);
135169689Skandouble_int double_int_zext (double_int, unsigned);
136169689Skan
137169689Skan#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
138169689Skan
139169689Skan/* The operands of the following comparison functions must be processed
140169689Skan   with double_int_ext, if their precision is less than
141169689Skan   2 * HOST_BITS_PER_WIDE_INT bits.  */
142169689Skan
143169689Skan/* Returns true if CST is zero.  */
144169689Skan
145169689Skanstatic inline bool
146169689Skandouble_int_zero_p (double_int cst)
147169689Skan{
148169689Skan  return cst.low == 0 && cst.high == 0;
149169689Skan}
150169689Skan
151169689Skan/* Returns true if CST is one.  */
152169689Skan
153169689Skanstatic inline bool
154169689Skandouble_int_one_p (double_int cst)
155169689Skan{
156169689Skan  return cst.low == 1 && cst.high == 0;
157169689Skan}
158169689Skan
159169689Skan/* Returns true if CST is minus one.  */
160169689Skan
161169689Skanstatic inline bool
162169689Skandouble_int_minus_one_p (double_int cst)
163169689Skan{
164169689Skan  return (cst.low == ALL_ONES && cst.high == -1);
165169689Skan}
166169689Skan
167169689Skan/* Returns true if CST1 == CST2.  */
168169689Skan
169169689Skanstatic inline bool
170169689Skandouble_int_equal_p (double_int cst1, double_int cst2)
171169689Skan{
172169689Skan  return cst1.low == cst2.low && cst1.high == cst2.high;
173169689Skan}
174169689Skan
175169689Skan#endif /* DOUBLE_INT_H */
176