Mercurial > hg > CbC > CbC_gcc
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 */ |