0
|
1 /* Operations with long integers.
|
|
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
|
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
|
8 Free Software Foundation; either version 3, or (at your option) any
|
|
9 later version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GCC; see the file COPYING3. If not see
|
|
18 <http://www.gnu.org/licenses/>. */
|
|
19
|
|
20 #ifndef DOUBLE_INT_H
|
|
21 #define DOUBLE_INT_H
|
|
22
|
|
23 #ifndef GENERATOR_FILE
|
|
24 #include <gmp.h>
|
|
25 #endif
|
|
26 #include "coretypes.h"
|
|
27
|
|
28 /* A large integer is currently represented as a pair of HOST_WIDE_INTs.
|
|
29 It therefore represents a number with precision of
|
|
30 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
|
|
31 internal representation will change, if numbers with greater precision
|
|
32 are needed, so the users should not rely on it). The representation does
|
|
33 not contain any information about signedness of the represented value, so
|
|
34 it can be used to represent both signed and unsigned numbers. For
|
|
35 operations where the results depend on signedness (division, comparisons),
|
|
36 it must be specified separately. For each such operation, there are three
|
|
37 versions of the function -- double_int_op, that takes an extra UNS argument
|
|
38 giving the signedness of the values, and double_int_sop and double_int_uop
|
|
39 that stand for its specializations for signed and unsigned values.
|
|
40
|
|
41 You may also represent with numbers in smaller precision using double_int.
|
|
42 You however need to use double_int_ext (that fills in the bits of the
|
|
43 number over the prescribed precision with zeros or with the sign bit) before
|
|
44 operations that do not perform arithmetics modulo 2^precision (comparisons,
|
|
45 division), and possibly before storing the results, if you want to keep
|
|
46 them in some canonical form). In general, the signedness of double_int_ext
|
|
47 should match the signedness of the operation.
|
|
48
|
|
49 ??? The components of double_int differ in signedness mostly for
|
|
50 historical reasons (they replace an older structure used to represent
|
|
51 numbers with precision higher than HOST_WIDE_INT). It might be less
|
|
52 confusing to have them both signed or both unsigned. */
|
|
53
|
|
54 typedef struct
|
|
55 {
|
|
56 unsigned HOST_WIDE_INT low;
|
|
57 HOST_WIDE_INT high;
|
|
58 } double_int;
|
|
59
|
|
60 union tree_node;
|
|
61
|
|
62 /* Constructors and conversions. */
|
|
63
|
|
64 union tree_node *double_int_to_tree (union tree_node *, double_int);
|
|
65 bool double_int_fits_to_tree_p (const union tree_node *, double_int);
|
|
66 double_int tree_to_double_int (const union tree_node *);
|
|
67
|
|
68 /* Constructs double_int from integer CST. The bits over the precision of
|
|
69 HOST_WIDE_INT are filled with the sign bit. */
|
|
70
|
|
71 static inline double_int
|
|
72 shwi_to_double_int (HOST_WIDE_INT cst)
|
|
73 {
|
|
74 double_int r;
|
|
75
|
|
76 r.low = (unsigned HOST_WIDE_INT) cst;
|
|
77 r.high = cst < 0 ? -1 : 0;
|
|
78
|
|
79 return r;
|
|
80 }
|
|
81
|
|
82 /* Some useful constants. */
|
|
83
|
|
84 #define double_int_minus_one (shwi_to_double_int (-1))
|
|
85 #define double_int_zero (shwi_to_double_int (0))
|
|
86 #define double_int_one (shwi_to_double_int (1))
|
|
87 #define double_int_two (shwi_to_double_int (2))
|
|
88 #define double_int_ten (shwi_to_double_int (10))
|
|
89
|
|
90 /* Constructs double_int from unsigned integer CST. The bits over the
|
|
91 precision of HOST_WIDE_INT are filled with zeros. */
|
|
92
|
|
93 static inline double_int
|
|
94 uhwi_to_double_int (unsigned HOST_WIDE_INT cst)
|
|
95 {
|
|
96 double_int r;
|
|
97
|
|
98 r.low = cst;
|
|
99 r.high = 0;
|
|
100
|
|
101 return r;
|
|
102 }
|
|
103
|
|
104 /* The following operations perform arithmetics modulo 2^precision,
|
|
105 so you do not need to call double_int_ext between them, even if
|
|
106 you are representing numbers with precision less than
|
|
107 2 * HOST_BITS_PER_WIDE_INT bits. */
|
|
108
|
|
109 double_int double_int_mul (double_int, double_int);
|
|
110 double_int double_int_add (double_int, double_int);
|
|
111 double_int double_int_neg (double_int);
|
|
112
|
|
113 /* You must ensure that double_int_ext is called on the operands
|
|
114 of the following operations, if the precision of the numbers
|
|
115 is less than 2 * HOST_BITS_PER_WIDE_INT bits. */
|
|
116 bool double_int_fits_in_hwi_p (double_int, bool);
|
|
117 bool double_int_fits_in_shwi_p (double_int);
|
|
118 bool double_int_fits_in_uhwi_p (double_int);
|
|
119 HOST_WIDE_INT double_int_to_shwi (double_int);
|
|
120 unsigned HOST_WIDE_INT double_int_to_uhwi (double_int);
|
|
121 double_int double_int_div (double_int, double_int, bool, unsigned);
|
|
122 double_int double_int_sdiv (double_int, double_int, unsigned);
|
|
123 double_int double_int_udiv (double_int, double_int, unsigned);
|
|
124 double_int double_int_mod (double_int, double_int, bool, unsigned);
|
|
125 double_int double_int_smod (double_int, double_int, unsigned);
|
|
126 double_int double_int_umod (double_int, double_int, unsigned);
|
|
127 double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
|
|
128 double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
|
|
129 double_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
|
|
130 bool double_int_negative_p (double_int);
|
|
131 int double_int_cmp (double_int, double_int, bool);
|
|
132 int double_int_scmp (double_int, double_int);
|
|
133 int double_int_ucmp (double_int, double_int);
|
|
134 void dump_double_int (FILE *, double_int, bool);
|
|
135
|
|
136 /* Zero and sign extension of numbers in smaller precisions. */
|
|
137
|
|
138 double_int double_int_ext (double_int, unsigned, bool);
|
|
139 double_int double_int_sext (double_int, unsigned);
|
|
140 double_int double_int_zext (double_int, unsigned);
|
|
141 double_int double_int_mask (unsigned);
|
|
142
|
|
143 #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
|
|
144
|
|
145 /* The operands of the following comparison functions must be processed
|
|
146 with double_int_ext, if their precision is less than
|
|
147 2 * HOST_BITS_PER_WIDE_INT bits. */
|
|
148
|
|
149 /* Returns true if CST is zero. */
|
|
150
|
|
151 static inline bool
|
|
152 double_int_zero_p (double_int cst)
|
|
153 {
|
|
154 return cst.low == 0 && cst.high == 0;
|
|
155 }
|
|
156
|
|
157 /* Returns true if CST is one. */
|
|
158
|
|
159 static inline bool
|
|
160 double_int_one_p (double_int cst)
|
|
161 {
|
|
162 return cst.low == 1 && cst.high == 0;
|
|
163 }
|
|
164
|
|
165 /* Returns true if CST is minus one. */
|
|
166
|
|
167 static inline bool
|
|
168 double_int_minus_one_p (double_int cst)
|
|
169 {
|
|
170 return (cst.low == ALL_ONES && cst.high == -1);
|
|
171 }
|
|
172
|
|
173 /* Returns true if CST1 == CST2. */
|
|
174
|
|
175 static inline bool
|
|
176 double_int_equal_p (double_int cst1, double_int cst2)
|
|
177 {
|
|
178 return cst1.low == cst2.low && cst1.high == cst2.high;
|
|
179 }
|
|
180
|
|
181 #ifndef GENERATOR_FILE
|
|
182 /* Conversion to and from GMP integer representations. */
|
|
183
|
|
184 void mpz_set_double_int (mpz_t, double_int, bool);
|
|
185 double_int mpz_get_double_int (const_tree, mpz_t, bool);
|
|
186 #endif
|
|
187
|
|
188 #endif /* DOUBLE_INT_H */
|