comparison gcc/double-int.h @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Operations with long integers. 1 /* Operations with long integers.
2 Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc. 2 Copyright (C) 2006-2017 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it 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 7 under the terms of the GNU General Public License as published by the
17 along with GCC; see the file COPYING3. If not see 17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
19 19
20 #ifndef DOUBLE_INT_H 20 #ifndef DOUBLE_INT_H
21 #define DOUBLE_INT_H 21 #define DOUBLE_INT_H
22
23 #ifndef GENERATOR_FILE
24 #include <gmp.h>
25 #endif
26 #include "coretypes.h"
27 22
28 /* A large integer is currently represented as a pair of HOST_WIDE_INTs. 23 /* A large integer is currently represented as a pair of HOST_WIDE_INTs.
29 It therefore represents a number with precision of 24 It therefore represents a number with precision of
30 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the 25 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
31 internal representation will change, if numbers with greater precision 26 internal representation will change, if numbers with greater precision
49 ??? The components of double_int differ in signedness mostly for 44 ??? The components of double_int differ in signedness mostly for
50 historical reasons (they replace an older structure used to represent 45 historical reasons (they replace an older structure used to represent
51 numbers with precision higher than HOST_WIDE_INT). It might be less 46 numbers with precision higher than HOST_WIDE_INT). It might be less
52 confusing to have them both signed or both unsigned. */ 47 confusing to have them both signed or both unsigned. */
53 48
54 typedef struct 49 struct double_int
55 { 50 {
51 /* Normally, we would define constructors to create instances.
52 Two things prevent us from doing so.
53 First, defining a constructor makes the class non-POD in C++03,
54 and we certainly want double_int to be a POD.
55 Second, the GCC conding conventions prefer explicit conversion,
56 and explicit conversion operators are not available until C++11. */
57
58 static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
59 static double_int from_shwi (HOST_WIDE_INT cst);
60 static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
61
62 /* Construct from a fuffer of length LEN. BUFFER will be read according
63 to byte endianness and word endianness. */
64 static double_int from_buffer (const unsigned char *buffer, int len);
65
66 /* No copy assignment operator or destructor to keep the type a POD. */
67
68 /* There are some special value-creation static member functions. */
69
70 static double_int mask (unsigned prec);
71 static double_int max_value (unsigned int prec, bool uns);
72 static double_int min_value (unsigned int prec, bool uns);
73
74 /* The following functions are mutating operations. */
75
76 double_int &operator ++ (); // prefix
77 double_int &operator -- (); // prefix
78 double_int &operator *= (double_int);
79 double_int &operator += (double_int);
80 double_int &operator -= (double_int);
81 double_int &operator &= (double_int);
82 double_int &operator ^= (double_int);
83 double_int &operator |= (double_int);
84
85 /* The following functions are non-mutating operations. */
86
87 /* Conversion functions. */
88
89 HOST_WIDE_INT to_shwi () const;
90 unsigned HOST_WIDE_INT to_uhwi () const;
91
92 /* Conversion query functions. */
93
94 bool fits_uhwi () const;
95 bool fits_shwi () const;
96 bool fits_hwi (bool uns) const;
97
98 /* Attribute query functions. */
99
100 int trailing_zeros () const;
101 int popcount () const;
102
103 /* Arithmetic query operations. */
104
105 bool multiple_of (double_int, bool, double_int *) const;
106
107 /* Arithmetic operation functions. */
108
109 /* The following operations perform arithmetics modulo 2^precision, so you
110 do not need to call .ext between them, even if you are representing
111 numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
112
113 double_int set_bit (unsigned) const;
114 double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
115 double_int wide_mul_with_sign (double_int, bool unsigned_p,
116 double_int *higher, bool *overflow) const;
117 double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
118 double_int sub_with_overflow (double_int, bool *overflow) const;
119 double_int neg_with_overflow (bool *overflow) const;
120
121 double_int operator * (double_int) const;
122 double_int operator + (double_int) const;
123 double_int operator - (double_int) const;
124 double_int operator - () const;
125 double_int operator ~ () const;
126 double_int operator & (double_int) const;
127 double_int operator | (double_int) const;
128 double_int operator ^ (double_int) const;
129 double_int and_not (double_int) const;
130
131 double_int lshift (HOST_WIDE_INT count) const;
132 double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
133 double_int rshift (HOST_WIDE_INT count) const;
134 double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
135 double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
136 double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
137 double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
138 double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
139 double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
140 double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;
141
142 /* You must ensure that double_int::ext is called on the operands
143 of the following operations, if the precision of the numbers
144 is less than HOST_BITS_PER_DOUBLE_INT bits. */
145
146 double_int div (double_int, bool, unsigned) const;
147 double_int sdiv (double_int, unsigned) const;
148 double_int udiv (double_int, unsigned) const;
149 double_int mod (double_int, bool, unsigned) const;
150 double_int smod (double_int, unsigned) const;
151 double_int umod (double_int, unsigned) const;
152 double_int divmod_with_overflow (double_int, bool, unsigned,
153 double_int *, bool *) const;
154 double_int divmod (double_int, bool, unsigned, double_int *) const;
155 double_int sdivmod (double_int, unsigned, double_int *) const;
156 double_int udivmod (double_int, unsigned, double_int *) const;
157
158 /* Precision control functions. */
159
160 double_int ext (unsigned prec, bool uns) const;
161 double_int zext (unsigned prec) const;
162 double_int sext (unsigned prec) const;
163
164 /* Comparative functions. */
165
166 bool is_zero () const;
167 bool is_one () const;
168 bool is_minus_one () const;
169 bool is_negative () const;
170
171 int cmp (double_int b, bool uns) const;
172 int ucmp (double_int b) const;
173 int scmp (double_int b) const;
174
175 bool ult (double_int b) const;
176 bool ule (double_int b) const;
177 bool ugt (double_int b) const;
178 bool slt (double_int b) const;
179 bool sle (double_int b) const;
180 bool sgt (double_int b) const;
181
182 double_int max (double_int b, bool uns);
183 double_int smax (double_int b);
184 double_int umax (double_int b);
185
186 double_int min (double_int b, bool uns);
187 double_int smin (double_int b);
188 double_int umin (double_int b);
189
190 bool operator == (double_int cst2) const;
191 bool operator != (double_int cst2) const;
192
193 /* Please migrate away from using these member variables publicly. */
194
56 unsigned HOST_WIDE_INT low; 195 unsigned HOST_WIDE_INT low;
57 HOST_WIDE_INT high; 196 HOST_WIDE_INT high;
58 } double_int; 197
198 };
59 199
60 #define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT) 200 #define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
61 201
62 /* Constructors and conversions. */ 202 /* Constructors and conversions. */
63 203
64 /* Constructs double_int from integer CST. The bits over the precision of 204 /* Constructs double_int from integer CST. The bits over the precision of
65 HOST_WIDE_INT are filled with the sign bit. */ 205 HOST_WIDE_INT are filled with the sign bit. */
66 206
67 static inline double_int 207 inline double_int
68 shwi_to_double_int (HOST_WIDE_INT cst) 208 double_int::from_shwi (HOST_WIDE_INT cst)
69 { 209 {
70 double_int r; 210 double_int r;
71
72 r.low = (unsigned HOST_WIDE_INT) cst; 211 r.low = (unsigned HOST_WIDE_INT) cst;
73 r.high = cst < 0 ? -1 : 0; 212 r.high = cst < 0 ? -1 : 0;
74
75 return r; 213 return r;
76 } 214 }
77 215
78 /* Some useful constants. */ 216 /* Some useful constants. */
79 217 /* FIXME(crowl): Maybe remove after converting callers?
80 #define double_int_minus_one (shwi_to_double_int (-1)) 218 The problem is that a named constant would not be as optimizable,
81 #define double_int_zero (shwi_to_double_int (0)) 219 while the functional syntax is more verbose. */
82 #define double_int_one (shwi_to_double_int (1)) 220
83 #define double_int_two (shwi_to_double_int (2)) 221 #define double_int_minus_one (double_int::from_shwi (-1))
84 #define double_int_ten (shwi_to_double_int (10)) 222 #define double_int_zero (double_int::from_shwi (0))
223 #define double_int_one (double_int::from_shwi (1))
224 #define double_int_two (double_int::from_shwi (2))
225 #define double_int_ten (double_int::from_shwi (10))
85 226
86 /* Constructs double_int from unsigned integer CST. The bits over the 227 /* Constructs double_int from unsigned integer CST. The bits over the
87 precision of HOST_WIDE_INT are filled with zeros. */ 228 precision of HOST_WIDE_INT are filled with zeros. */
88 229
89 static inline double_int 230 inline double_int
90 uhwi_to_double_int (unsigned HOST_WIDE_INT cst) 231 double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
91 { 232 {
92 double_int r; 233 double_int r;
93
94 r.low = cst; 234 r.low = cst;
95 r.high = 0; 235 r.high = 0;
96
97 return r; 236 return r;
98 } 237 }
99 238
239 inline double_int
240 double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
241 {
242 double_int r;
243 r.low = low;
244 r.high = high;
245 return r;
246 }
247
248 inline double_int &
249 double_int::operator ++ ()
250 {
251 *this += double_int_one;
252 return *this;
253 }
254
255 inline double_int &
256 double_int::operator -- ()
257 {
258 *this -= double_int_one;
259 return *this;
260 }
261
262 inline double_int &
263 double_int::operator &= (double_int b)
264 {
265 *this = *this & b;
266 return *this;
267 }
268
269 inline double_int &
270 double_int::operator ^= (double_int b)
271 {
272 *this = *this ^ b;
273 return *this;
274 }
275
276 inline double_int &
277 double_int::operator |= (double_int b)
278 {
279 *this = *this | b;
280 return *this;
281 }
282
100 /* Returns value of CST as a signed number. CST must satisfy 283 /* Returns value of CST as a signed number. CST must satisfy
101 double_int_fits_in_shwi_p. */ 284 double_int::fits_signed. */
102 285
103 static inline HOST_WIDE_INT 286 inline HOST_WIDE_INT
104 double_int_to_shwi (double_int cst) 287 double_int::to_shwi () const
105 { 288 {
106 return (HOST_WIDE_INT) cst.low; 289 return (HOST_WIDE_INT) low;
107 } 290 }
108 291
109 /* Returns value of CST as an unsigned number. CST must satisfy 292 /* Returns value of CST as an unsigned number. CST must satisfy
110 double_int_fits_in_uhwi_p. */ 293 double_int::fits_unsigned. */
111 294
112 static inline unsigned HOST_WIDE_INT 295 inline unsigned HOST_WIDE_INT
113 double_int_to_uhwi (double_int cst) 296 double_int::to_uhwi () const
114 { 297 {
115 return cst.low; 298 return low;
116 } 299 }
117
118 bool double_int_fits_in_hwi_p (double_int, bool);
119 bool double_int_fits_in_shwi_p (double_int);
120 300
121 /* Returns true if CST fits in unsigned HOST_WIDE_INT. */ 301 /* Returns true if CST fits in unsigned HOST_WIDE_INT. */
122 302
123 static inline bool 303 inline bool
124 double_int_fits_in_uhwi_p (double_int cst) 304 double_int::fits_uhwi () const
125 { 305 {
126 return cst.high == 0; 306 return high == 0;
127 } 307 }
128
129 /* The following operations perform arithmetics modulo 2^precision,
130 so you do not need to call double_int_ext between them, even if
131 you are representing numbers with precision less than
132 2 * HOST_BITS_PER_WIDE_INT bits. */
133
134 double_int double_int_mul (double_int, double_int);
135 double_int double_int_mul_with_sign (double_int, double_int, bool, int *);
136 double_int double_int_add (double_int, double_int);
137 double_int double_int_sub (double_int, double_int);
138 double_int double_int_neg (double_int);
139
140 /* You must ensure that double_int_ext is called on the operands
141 of the following operations, if the precision of the numbers
142 is less than 2 * HOST_BITS_PER_WIDE_INT bits. */
143 double_int double_int_div (double_int, double_int, bool, unsigned);
144 double_int double_int_sdiv (double_int, double_int, unsigned);
145 double_int double_int_udiv (double_int, double_int, unsigned);
146 double_int double_int_mod (double_int, double_int, bool, unsigned);
147 double_int double_int_smod (double_int, double_int, unsigned);
148 double_int double_int_umod (double_int, double_int, unsigned);
149 double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *);
150 double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *);
151 double_int double_int_udivmod (double_int, double_int, unsigned, double_int *);
152
153 double_int double_int_setbit (double_int, unsigned);
154 int double_int_ctz (double_int);
155 308
156 /* Logical operations. */ 309 /* Logical operations. */
157 310
158 /* Returns ~A. */ 311 /* Returns ~A. */
159 312
160 static inline double_int 313 inline double_int
161 double_int_not (double_int a) 314 double_int::operator ~ () const
162 { 315 {
163 a.low = ~a.low; 316 double_int result;
164 a.high = ~a.high; 317 result.low = ~low;
165 return a; 318 result.high = ~high;
319 return result;
166 } 320 }
167 321
168 /* Returns A | B. */ 322 /* Returns A | B. */
169 323
170 static inline double_int 324 inline double_int
171 double_int_ior (double_int a, double_int b) 325 double_int::operator | (double_int b) const
172 { 326 {
173 a.low |= b.low; 327 double_int result;
174 a.high |= b.high; 328 result.low = low | b.low;
175 return a; 329 result.high = high | b.high;
330 return result;
176 } 331 }
177 332
178 /* Returns A & B. */ 333 /* Returns A & B. */
179 334
180 static inline double_int 335 inline double_int
181 double_int_and (double_int a, double_int b) 336 double_int::operator & (double_int b) const
182 { 337 {
183 a.low &= b.low; 338 double_int result;
184 a.high &= b.high; 339 result.low = low & b.low;
185 return a; 340 result.high = high & b.high;
341 return result;
186 } 342 }
187 343
188 /* Returns A & ~B. */ 344 /* Returns A & ~B. */
189 345
190 static inline double_int 346 inline double_int
191 double_int_and_not (double_int a, double_int b) 347 double_int::and_not (double_int b) const
192 { 348 {
193 a.low &= ~b.low; 349 double_int result;
194 a.high &= ~b.high; 350 result.low = low & ~b.low;
195 return a; 351 result.high = high & ~b.high;
352 return result;
196 } 353 }
197 354
198 /* Returns A ^ B. */ 355 /* Returns A ^ B. */
199 356
200 static inline double_int 357 inline double_int
201 double_int_xor (double_int a, double_int b) 358 double_int::operator ^ (double_int b) const
202 { 359 {
203 a.low ^= b.low; 360 double_int result;
204 a.high ^= b.high; 361 result.low = low ^ b.low;
205 return a; 362 result.high = high ^ b.high;
206 } 363 return result;
207 364 }
208
209 /* Shift operations. */
210 double_int double_int_lshift (double_int, HOST_WIDE_INT, unsigned int, bool);
211 double_int double_int_rshift (double_int, HOST_WIDE_INT, unsigned int, bool);
212 double_int double_int_lrotate (double_int, HOST_WIDE_INT, unsigned int);
213 double_int double_int_rrotate (double_int, HOST_WIDE_INT, unsigned int);
214
215 /* Returns true if CST is negative. Of course, CST is considered to
216 be signed. */
217
218 static inline bool
219 double_int_negative_p (double_int cst)
220 {
221 return cst.high < 0;
222 }
223
224 int double_int_cmp (double_int, double_int, bool);
225 int double_int_scmp (double_int, double_int);
226 int double_int_ucmp (double_int, double_int);
227
228 double_int double_int_max (double_int, double_int, bool);
229 double_int double_int_smax (double_int, double_int);
230 double_int double_int_umax (double_int, double_int);
231
232 double_int double_int_min (double_int, double_int, bool);
233 double_int double_int_smin (double_int, double_int);
234 double_int double_int_umin (double_int, double_int);
235 365
236 void dump_double_int (FILE *, double_int, bool); 366 void dump_double_int (FILE *, double_int, bool);
237 367
238 /* Zero and sign extension of numbers in smaller precisions. */ 368 #define ALL_ONES HOST_WIDE_INT_M1U
239
240 double_int double_int_ext (double_int, unsigned, bool);
241 double_int double_int_sext (double_int, unsigned);
242 double_int double_int_zext (double_int, unsigned);
243 double_int double_int_mask (unsigned);
244
245 #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
246 369
247 /* The operands of the following comparison functions must be processed 370 /* The operands of the following comparison functions must be processed
248 with double_int_ext, if their precision is less than 371 with double_int_ext, if their precision is less than
249 2 * HOST_BITS_PER_WIDE_INT bits. */ 372 HOST_BITS_PER_DOUBLE_INT bits. */
250 373
251 /* Returns true if CST is zero. */ 374 /* Returns true if CST is zero. */
252 375
253 static inline bool 376 inline bool
254 double_int_zero_p (double_int cst) 377 double_int::is_zero () const
255 { 378 {
256 return cst.low == 0 && cst.high == 0; 379 return low == 0 && high == 0;
257 } 380 }
258 381
259 /* Returns true if CST is one. */ 382 /* Returns true if CST is one. */
260 383
261 static inline bool 384 inline bool
262 double_int_one_p (double_int cst) 385 double_int::is_one () const
263 { 386 {
264 return cst.low == 1 && cst.high == 0; 387 return low == 1 && high == 0;
265 } 388 }
266 389
267 /* Returns true if CST is minus one. */ 390 /* Returns true if CST is minus one. */
268 391
269 static inline bool 392 inline bool
270 double_int_minus_one_p (double_int cst) 393 double_int::is_minus_one () const
271 { 394 {
272 return (cst.low == ALL_ONES && cst.high == -1); 395 return low == ALL_ONES && high == -1;
396 }
397
398 /* Returns true if CST is negative. */
399
400 inline bool
401 double_int::is_negative () const
402 {
403 return high < 0;
273 } 404 }
274 405
275 /* Returns true if CST1 == CST2. */ 406 /* Returns true if CST1 == CST2. */
276 407
277 static inline bool 408 inline bool
278 double_int_equal_p (double_int cst1, double_int cst2) 409 double_int::operator == (double_int cst2) const
279 { 410 {
280 return cst1.low == cst2.low && cst1.high == cst2.high; 411 return low == cst2.low && high == cst2.high;
281 } 412 }
282 413
283 414 /* Returns true if CST1 != CST2. */
284 /* Legacy interface with decomposed high/low parts. */ 415
285 416 inline bool
286 extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, 417 double_int::operator != (double_int cst2) const
287 unsigned HOST_WIDE_INT, HOST_WIDE_INT, 418 {
288 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, 419 return low != cst2.low || high != cst2.high;
289 bool); 420 }
290 #define add_double(l1,h1,l2,h2,lv,hv) \ 421
291 add_double_with_sign (l1, h1, l2, h2, lv, hv, false) 422 /* Return number of set bits of CST. */
292 extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, 423
293 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *); 424 inline int
294 extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, 425 double_int::popcount () const
295 unsigned HOST_WIDE_INT, HOST_WIDE_INT, 426 {
296 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, 427 return popcount_hwi (high) + popcount_hwi (low);
297 bool); 428 }
298 #define mul_double(l1,h1,l2,h2,lv,hv) \
299 mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
300 extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
301 HOST_WIDE_INT, unsigned int,
302 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
303 extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
304 HOST_WIDE_INT, unsigned int,
305 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
306 extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
307 HOST_WIDE_INT, unsigned HOST_WIDE_INT,
308 HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
309 HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
310 HOST_WIDE_INT *);
311 429
312 430
313 #ifndef GENERATOR_FILE 431 #ifndef GENERATOR_FILE
314 /* Conversion to and from GMP integer representations. */ 432 /* Conversion to and from GMP integer representations. */
315 433
316 void mpz_set_double_int (mpz_t, double_int, bool); 434 void mpz_set_double_int (mpz_t, double_int, bool);
317 double_int mpz_get_double_int (const_tree, mpz_t, bool); 435 double_int mpz_get_double_int (const_tree, mpz_t, bool);
318 #endif 436 #endif
319 437
438 namespace wi
439 {
440 template <>
441 struct int_traits <double_int>
442 {
443 static const enum precision_type precision_type = CONST_PRECISION;
444 static const bool host_dependent_precision = true;
445 static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT;
446 static unsigned int get_precision (const double_int &);
447 static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
448 const double_int &);
449 };
450 }
451
452 inline unsigned int
453 wi::int_traits <double_int>::get_precision (const double_int &)
454 {
455 return precision;
456 }
457
458 inline wi::storage_ref
459 wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p,
460 const double_int &x)
461 {
462 gcc_checking_assert (precision == p);
463 scratch[0] = x.low;
464 if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0))
465 return wi::storage_ref (scratch, 1, precision);
466 scratch[1] = x.high;
467 return wi::storage_ref (scratch, 2, precision);
468 }
469
320 #endif /* DOUBLE_INT_H */ 470 #endif /* DOUBLE_INT_H */