Bug Summary

File:build/gcc/wide-int.cc
Warning:line 1859, column 22
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name wide-int.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/13.0.0 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/backward -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-error=format-diag -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2021-11-20-133755-20252-1/report-dMOTJE.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc

1/* Operations with very long integers.
2 Copyright (C) 2012-2021 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3, or (at your option) any
10later version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "tree.h"
26#include "selftest.h"
27
28
29#define HOST_BITS_PER_HALF_WIDE_INT32 32
30#if HOST_BITS_PER_HALF_WIDE_INT32 == HOST_BITS_PER_LONG(8 * 8)
31# define HOST_HALF_WIDE_INTint long
32#elif HOST_BITS_PER_HALF_WIDE_INT32 == HOST_BITS_PER_INT(8 * 4)
33# define HOST_HALF_WIDE_INTint int
34#else
35#error Please add support for HOST_HALF_WIDE_INTint
36#endif
37
38#define W_TYPE_SIZE64 HOST_BITS_PER_WIDE_INT64
39/* Do not include longlong.h when compiler is clang-based. See PR61146. */
40#if GCC_VERSION(4 * 1000 + 2) >= 3000 && (W_TYPE_SIZE64 == 32 || defined (__SIZEOF_INT128__16)) && !defined(__clang__1)
41typedef unsigned HOST_HALF_WIDE_INTint UHWtype;
42typedef unsigned HOST_WIDE_INTlong UWtype;
43typedef unsigned int UQItype __attribute__ ((mode (QI)));
44typedef unsigned int USItype __attribute__ ((mode (SI)));
45typedef unsigned int UDItype __attribute__ ((mode (DI)));
46#if W_TYPE_SIZE64 == 32
47typedef unsigned int UDWtype __attribute__ ((mode (DI)));
48#else
49typedef unsigned int UDWtype __attribute__ ((mode (TI)));
50#endif
51#include "longlong.h"
52#endif
53
54static const HOST_WIDE_INTlong zeros[WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64)] = {};
55
56/*
57 * Internal utilities.
58 */
59
60/* Quantities to deal with values that hold half of a wide int. Used
61 in multiply and divide. */
62#define HALF_INT_MASK((1L << 32) - 1) ((HOST_WIDE_INT_11L << HOST_BITS_PER_HALF_WIDE_INT32) - 1)
63
64#define BLOCK_OF(TARGET)((TARGET) / 64) ((TARGET) / HOST_BITS_PER_WIDE_INT64)
65#define BLOCKS_NEEDED(PREC)(PREC ? (((PREC) + 64 - 1) / 64) : 1) \
66 (PREC ? (((PREC) + HOST_BITS_PER_WIDE_INT64 - 1) / HOST_BITS_PER_WIDE_INT64) : 1)
67#define SIGN_MASK(X)((long) (X) < 0 ? -1 : 0) ((HOST_WIDE_INTlong) (X) < 0 ? -1 : 0)
68
69/* Return the value a VAL[I] if I < LEN, otherwise, return 0 or -1
70 based on the top existing bit of VAL. */
71
72static unsigned HOST_WIDE_INTlong
73safe_uhwi (const HOST_WIDE_INTlong *val, unsigned int len, unsigned int i)
74{
75 return i < len ? val[i] : val[len - 1] < 0 ? HOST_WIDE_INT_M1-1L : 0;
76}
77
78/* Convert the integer in VAL to canonical form, returning its new length.
79 LEN is the number of blocks currently in VAL and PRECISION is the number
80 of bits in the integer it represents.
81
82 This function only changes the representation, not the value. */
83static unsigned int
84canonize (HOST_WIDE_INTlong *val, unsigned int len, unsigned int precision)
85{
86 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
87 HOST_WIDE_INTlong top;
88 int i;
89
90 if (len > blocks_needed)
91 len = blocks_needed;
92
93 if (len == 1)
94 return len;
95
96 top = val[len - 1];
97 if (len * HOST_BITS_PER_WIDE_INT64 > precision)
98 val[len - 1] = top = sext_hwi (top, precision % HOST_BITS_PER_WIDE_INT64);
99 if (top != 0 && top != (HOST_WIDE_INTlong)-1)
100 return len;
101
102 /* At this point we know that the top is either 0 or -1. Find the
103 first block that is not a copy of this. */
104 for (i = len - 2; i >= 0; i--)
105 {
106 HOST_WIDE_INTlong x = val[i];
107 if (x != top)
108 {
109 if (SIGN_MASK (x)((long) (x) < 0 ? -1 : 0) == top)
110 return i + 1;
111
112 /* We need an extra block because the top bit block i does
113 not match the extension. */
114 return i + 2;
115 }
116 }
117
118 /* The number is 0 or -1. */
119 return 1;
120}
121
122/* VAL[0] is the unsigned result of an operation. Canonize it by adding
123 another 0 block if needed, and return number of blocks needed. */
124
125static inline unsigned int
126canonize_uhwi (HOST_WIDE_INTlong *val, unsigned int precision)
127{
128 if (val[0] < 0 && precision > HOST_BITS_PER_WIDE_INT64)
129 {
130 val[1] = 0;
131 return 2;
132 }
133 return 1;
134}
135
136/*
137 * Conversion routines in and out of wide_int.
138 */
139
140/* Copy XLEN elements from XVAL to VAL. If NEED_CANON, canonize the
141 result for an integer with precision PRECISION. Return the length
142 of VAL (after any canonization. */
143unsigned int
144wi::from_array (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
145 unsigned int xlen, unsigned int precision, bool need_canon)
146{
147 for (unsigned i = 0; i < xlen; i++)
148 val[i] = xval[i];
149 return need_canon ? canonize (val, xlen, precision) : xlen;
150}
151
152/* Construct a wide int from a buffer of length LEN. BUFFER will be
153 read according to byte endianness and word endianness of the target.
154 Only the lower BUFFER_LEN bytes of the result are set; the remaining
155 high bytes are cleared. */
156wide_int
157wi::from_buffer (const unsigned char *buffer, unsigned int buffer_len)
158{
159 unsigned int precision = buffer_len * BITS_PER_UNIT(8);
160 wide_int result = wide_int::create (precision);
161 unsigned int words = buffer_len / UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
162
163 /* We have to clear all the bits ourself, as we merely or in values
164 below. */
165 unsigned int len = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
166 HOST_WIDE_INTlong *val = result.write_val ();
167 for (unsigned int i = 0; i < len; ++i)
168 val[i] = 0;
169
170 for (unsigned int byte = 0; byte < buffer_len; byte++)
171 {
172 unsigned int offset;
173 unsigned int index;
174 unsigned int bitpos = byte * BITS_PER_UNIT(8);
175 unsigned HOST_WIDE_INTlong value;
176
177 if (buffer_len > UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
)
178 {
179 unsigned int word = byte / UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
180
181 if (WORDS_BIG_ENDIAN0)
182 word = (words - 1) - word;
183
184 offset = word * UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
185
186 if (BYTES_BIG_ENDIAN0)
187 offset += (UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
- 1) - (byte % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
);
188 else
189 offset += byte % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
190 }
191 else
192 offset = BYTES_BIG_ENDIAN0 ? (buffer_len - 1) - byte : byte;
193
194 value = (unsigned HOST_WIDE_INTlong) buffer[offset];
195
196 index = bitpos / HOST_BITS_PER_WIDE_INT64;
197 val[index] |= value << (bitpos % HOST_BITS_PER_WIDE_INT64);
198 }
199
200 result.set_len (canonize (val, len, precision));
201
202 return result;
203}
204
205/* Sets RESULT from X, the sign is taken according to SGN. */
206void
207wi::to_mpz (const wide_int_ref &x, mpz_t result, signop sgn)
208{
209 int len = x.get_len ();
210 const HOST_WIDE_INTlong *v = x.get_val ();
211 int excess = len * HOST_BITS_PER_WIDE_INT64 - x.get_precision ();
212
213 if (wi::neg_p (x, sgn))
214 {
215 /* We use ones complement to avoid -x80..0 edge case that -
216 won't work on. */
217 HOST_WIDE_INTlong *t = XALLOCAVEC (HOST_WIDE_INT, len)((long *) __builtin_alloca(sizeof (long) * (len)));
218 for (int i = 0; i < len; i++)
219 t[i] = ~v[i];
220 if (excess > 0)
221 t[len - 1] = (unsigned HOST_WIDE_INTlong) t[len - 1] << excess >> excess;
222 mpz_import__gmpz_import (result, len, -1, sizeof (HOST_WIDE_INTlong), 0, 0, t);
223 mpz_com__gmpz_com (result, result);
224 }
225 else if (excess > 0)
226 {
227 HOST_WIDE_INTlong *t = XALLOCAVEC (HOST_WIDE_INT, len)((long *) __builtin_alloca(sizeof (long) * (len)));
228 for (int i = 0; i < len - 1; i++)
229 t[i] = v[i];
230 t[len - 1] = (unsigned HOST_WIDE_INTlong) v[len - 1] << excess >> excess;
231 mpz_import__gmpz_import (result, len, -1, sizeof (HOST_WIDE_INTlong), 0, 0, t);
232 }
233 else if (excess < 0 && wi::neg_p (x))
234 {
235 int extra
236 = (-excess + HOST_BITS_PER_WIDE_INT64 - 1) / HOST_BITS_PER_WIDE_INT64;
237 HOST_WIDE_INTlong *t = XALLOCAVEC (HOST_WIDE_INT, len + extra)((long *) __builtin_alloca(sizeof (long) * (len + extra)));
238 for (int i = 0; i < len; i++)
239 t[i] = v[i];
240 for (int i = 0; i < extra; i++)
241 t[len + i] = -1;
242 excess = (-excess) % HOST_BITS_PER_WIDE_INT64;
243 if (excess)
244 t[len + extra - 1] = (HOST_WIDE_INT_1U1UL << excess) - 1;
245 mpz_import__gmpz_import (result, len + extra, -1, sizeof (HOST_WIDE_INTlong), 0, 0, t);
246 }
247 else
248 mpz_import__gmpz_import (result, len, -1, sizeof (HOST_WIDE_INTlong), 0, 0, v);
249}
250
251/* Returns X converted to TYPE. If WRAP is true, then out-of-range
252 values of VAL will be wrapped; otherwise, they will be set to the
253 appropriate minimum or maximum TYPE bound. */
254wide_int
255wi::from_mpz (const_tree type, mpz_t x, bool wrap)
256{
257 size_t count, numb;
258 unsigned int prec = TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 258, __FUNCTION__))->type_common.precision)
;
259 wide_int res = wide_int::create (prec);
260
261 if (!wrap)
262 {
263 mpz_t min, max;
264
265 mpz_init__gmpz_init (min);
266 mpz_init__gmpz_init (max);
267 get_type_static_bounds (type, min, max);
268
269 if (mpz_cmp__gmpz_cmp (x, min) < 0)
270 mpz_set__gmpz_set (x, min);
271 else if (mpz_cmp__gmpz_cmp (x, max) > 0)
272 mpz_set__gmpz_set (x, max);
273
274 mpz_clear__gmpz_clear (min);
275 mpz_clear__gmpz_clear (max);
276 }
277
278 /* Determine the number of unsigned HOST_WIDE_INTs that are required
279 for representing the absolute value. The code to calculate count is
280 extracted from the GMP manual, section "Integer Import and Export":
281 http://gmplib.org/manual/Integer-Import-and-Export.html */
282 numb = CHAR_BIT8 * sizeof (HOST_WIDE_INTlong);
283 count = (mpz_sizeinbase__gmpz_sizeinbase (x, 2) + numb - 1) / numb;
284 HOST_WIDE_INTlong *val = res.write_val ();
285 /* Read the absolute value.
286
287 Write directly to the wide_int storage if possible, otherwise leave
288 GMP to allocate the memory for us. It might be slightly more efficient
289 to use mpz_tdiv_r_2exp for the latter case, but the situation is
290 pathological and it seems safer to operate on the original mpz value
291 in all cases. */
292 void *valres = mpz_export__gmpz_export (count <= WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64) ? val : 0,
293 &count, -1, sizeof (HOST_WIDE_INTlong), 0, 0, x);
294 if (count < 1)
295 {
296 val[0] = 0;
297 count = 1;
298 }
299 count = MIN (count, BLOCKS_NEEDED (prec))((count) < ((prec ? (((prec) + 64 - 1) / 64) : 1)) ? (count
) : ((prec ? (((prec) + 64 - 1) / 64) : 1)))
;
300 if (valres != val)
301 {
302 memcpy (val, valres, count * sizeof (HOST_WIDE_INTlong));
303 free (valres);
304 }
305 /* Zero-extend the absolute value to PREC bits. */
306 if (count < BLOCKS_NEEDED (prec)(prec ? (((prec) + 64 - 1) / 64) : 1) && val[count - 1] < 0)
307 val[count++] = 0;
308 else
309 count = canonize (val, count, prec);
310 res.set_len (count);
311
312 if (mpz_sgn (x)((x)->_mp_size < 0 ? -1 : (x)->_mp_size > 0) < 0)
313 res = -res;
314
315 return res;
316}
317
318/*
319 * Largest and smallest values in a mode.
320 */
321
322/* Return the largest SGNed number that is representable in PRECISION bits.
323
324 TODO: There is still code from the double_int era that trys to
325 make up for the fact that double int's could not represent the
326 min and max values of all types. This code should be removed
327 because the min and max values can always be represented in
328 wide_ints and int-csts. */
329wide_int
330wi::max_value (unsigned int precision, signop sgn)
331{
332 gcc_checking_assert (precision != 0)((void)(!(precision != 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 332, __FUNCTION__), 0 : 0))
;
333 if (sgn == UNSIGNED)
334 /* The unsigned max is just all ones. */
335 return shwi (-1, precision);
336 else
337 /* The signed max is all ones except the top bit. This must be
338 explicitly represented. */
339 return mask (precision - 1, false, precision);
340}
341
342/* Return the largest SGNed number that is representable in PRECISION bits. */
343wide_int
344wi::min_value (unsigned int precision, signop sgn)
345{
346 gcc_checking_assert (precision != 0)((void)(!(precision != 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 346, __FUNCTION__), 0 : 0))
;
347 if (sgn == UNSIGNED)
348 return uhwi (0, precision);
349 else
350 /* The signed min is all zeros except the top bit. This must be
351 explicitly represented. */
352 return wi::set_bit_in_zero (precision - 1, precision);
353}
354
355/*
356 * Public utilities.
357 */
358
359/* Convert the number represented by XVAL, XLEN and XPRECISION, which has
360 signedness SGN, to an integer that has PRECISION bits. Store the blocks
361 in VAL and return the number of blocks used.
362
363 This function can handle both extension (PRECISION > XPRECISION)
364 and truncation (PRECISION < XPRECISION). */
365unsigned int
366wi::force_to_size (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
367 unsigned int xlen, unsigned int xprecision,
368 unsigned int precision, signop sgn)
369{
370 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
371 unsigned int len = blocks_needed < xlen ? blocks_needed : xlen;
372 for (unsigned i = 0; i < len; i++)
373 val[i] = xval[i];
374
375 if (precision > xprecision)
376 {
377 unsigned int small_xprecision = xprecision % HOST_BITS_PER_WIDE_INT64;
378
379 /* Expanding. */
380 if (sgn == UNSIGNED)
381 {
382 if (small_xprecision && len == BLOCKS_NEEDED (xprecision)(xprecision ? (((xprecision) + 64 - 1) / 64) : 1))
383 val[len - 1] = zext_hwi (val[len - 1], small_xprecision);
384 else if (val[len - 1] < 0)
385 {
386 while (len < BLOCKS_NEEDED (xprecision)(xprecision ? (((xprecision) + 64 - 1) / 64) : 1))
387 val[len++] = -1;
388 if (small_xprecision)
389 val[len - 1] = zext_hwi (val[len - 1], small_xprecision);
390 else
391 val[len++] = 0;
392 }
393 }
394 else
395 {
396 if (small_xprecision && len == BLOCKS_NEEDED (xprecision)(xprecision ? (((xprecision) + 64 - 1) / 64) : 1))
397 val[len - 1] = sext_hwi (val[len - 1], small_xprecision);
398 }
399 }
400 len = canonize (val, len, precision);
401
402 return len;
403}
404
405/* This function hides the fact that we cannot rely on the bits beyond
406 the precision. This issue comes up in the relational comparisions
407 where we do allow comparisons of values of different precisions. */
408static inline HOST_WIDE_INTlong
409selt (const HOST_WIDE_INTlong *a, unsigned int len,
410 unsigned int blocks_needed, unsigned int small_prec,
411 unsigned int index, signop sgn)
412{
413 HOST_WIDE_INTlong val;
414 if (index < len)
415 val = a[index];
416 else if (index < blocks_needed || sgn == SIGNED)
417 /* Signed or within the precision. */
418 val = SIGN_MASK (a[len - 1])((long) (a[len - 1]) < 0 ? -1 : 0);
419 else
420 /* Unsigned extension beyond the precision. */
421 val = 0;
422
423 if (small_prec && index == blocks_needed - 1)
424 return (sgn == SIGNED
425 ? sext_hwi (val, small_prec)
426 : zext_hwi (val, small_prec));
427 else
428 return val;
429}
430
431/* Find the highest bit represented in a wide int. This will in
432 general have the same value as the sign bit. */
433static inline HOST_WIDE_INTlong
434top_bit_of (const HOST_WIDE_INTlong *a, unsigned int len, unsigned int prec)
435{
436 int excess = len * HOST_BITS_PER_WIDE_INT64 - prec;
437 unsigned HOST_WIDE_INTlong val = a[len - 1];
438 if (excess > 0)
439 val <<= excess;
440 return val >> (HOST_BITS_PER_WIDE_INT64 - 1);
441}
442
443/*
444 * Comparisons, note that only equality is an operator. The other
445 * comparisons cannot be operators since they are inherently signed or
446 * unsigned and C++ has no such operators.
447 */
448
449/* Return true if OP0 == OP1. */
450bool
451wi::eq_p_large (const HOST_WIDE_INTlong *op0, unsigned int op0len,
452 const HOST_WIDE_INTlong *op1, unsigned int op1len,
453 unsigned int prec)
454{
455 int l0 = op0len - 1;
456 unsigned int small_prec = prec & (HOST_BITS_PER_WIDE_INT64 - 1);
457
458 if (op0len != op1len)
459 return false;
460
461 if (op0len == BLOCKS_NEEDED (prec)(prec ? (((prec) + 64 - 1) / 64) : 1) && small_prec)
462 {
463 /* It does not matter if we zext or sext here, we just have to
464 do both the same way. */
465 if (zext_hwi (op0 [l0], small_prec) != zext_hwi (op1 [l0], small_prec))
466 return false;
467 l0--;
468 }
469
470 while (l0 >= 0)
471 if (op0[l0] != op1[l0])
472 return false;
473 else
474 l0--;
475
476 return true;
477}
478
479/* Return true if OP0 < OP1 using signed comparisons. */
480bool
481wi::lts_p_large (const HOST_WIDE_INTlong *op0, unsigned int op0len,
482 unsigned int precision,
483 const HOST_WIDE_INTlong *op1, unsigned int op1len)
484{
485 HOST_WIDE_INTlong s0, s1;
486 unsigned HOST_WIDE_INTlong u0, u1;
487 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
488 unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT64 - 1);
489 int l = MAX (op0len - 1, op1len - 1)((op0len - 1) > (op1len - 1) ? (op0len - 1) : (op1len - 1)
)
;
490
491 /* Only the top block is compared as signed. The rest are unsigned
492 comparisons. */
493 s0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED);
494 s1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED);
495 if (s0 < s1)
496 return true;
497 if (s0 > s1)
498 return false;
499
500 l--;
501 while (l >= 0)
502 {
503 u0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED);
504 u1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED);
505
506 if (u0 < u1)
507 return true;
508 if (u0 > u1)
509 return false;
510 l--;
511 }
512
513 return false;
514}
515
516/* Returns -1 if OP0 < OP1, 0 if OP0 == OP1 and 1 if OP0 > OP1 using
517 signed compares. */
518int
519wi::cmps_large (const HOST_WIDE_INTlong *op0, unsigned int op0len,
520 unsigned int precision,
521 const HOST_WIDE_INTlong *op1, unsigned int op1len)
522{
523 HOST_WIDE_INTlong s0, s1;
524 unsigned HOST_WIDE_INTlong u0, u1;
525 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
526 unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT64 - 1);
527 int l = MAX (op0len - 1, op1len - 1)((op0len - 1) > (op1len - 1) ? (op0len - 1) : (op1len - 1)
)
;
528
529 /* Only the top block is compared as signed. The rest are unsigned
530 comparisons. */
531 s0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED);
532 s1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED);
533 if (s0 < s1)
534 return -1;
535 if (s0 > s1)
536 return 1;
537
538 l--;
539 while (l >= 0)
540 {
541 u0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED);
542 u1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED);
543
544 if (u0 < u1)
545 return -1;
546 if (u0 > u1)
547 return 1;
548 l--;
549 }
550
551 return 0;
552}
553
554/* Return true if OP0 < OP1 using unsigned comparisons. */
555bool
556wi::ltu_p_large (const HOST_WIDE_INTlong *op0, unsigned int op0len,
557 unsigned int precision,
558 const HOST_WIDE_INTlong *op1, unsigned int op1len)
559{
560 unsigned HOST_WIDE_INTlong x0;
561 unsigned HOST_WIDE_INTlong x1;
562 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
563 unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT64 - 1);
564 int l = MAX (op0len - 1, op1len - 1)((op0len - 1) > (op1len - 1) ? (op0len - 1) : (op1len - 1)
)
;
565
566 while (l >= 0)
567 {
568 x0 = selt (op0, op0len, blocks_needed, small_prec, l, UNSIGNED);
569 x1 = selt (op1, op1len, blocks_needed, small_prec, l, UNSIGNED);
570 if (x0 < x1)
571 return true;
572 if (x0 > x1)
573 return false;
574 l--;
575 }
576
577 return false;
578}
579
580/* Returns -1 if OP0 < OP1, 0 if OP0 == OP1 and 1 if OP0 > OP1 using
581 unsigned compares. */
582int
583wi::cmpu_large (const HOST_WIDE_INTlong *op0, unsigned int op0len,
584 unsigned int precision,
585 const HOST_WIDE_INTlong *op1, unsigned int op1len)
586{
587 unsigned HOST_WIDE_INTlong x0;
588 unsigned HOST_WIDE_INTlong x1;
589 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
590 unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT64 - 1);
591 int l = MAX (op0len - 1, op1len - 1)((op0len - 1) > (op1len - 1) ? (op0len - 1) : (op1len - 1)
)
;
592
593 while (l >= 0)
594 {
595 x0 = selt (op0, op0len, blocks_needed, small_prec, l, UNSIGNED);
596 x1 = selt (op1, op1len, blocks_needed, small_prec, l, UNSIGNED);
597 if (x0 < x1)
598 return -1;
599 if (x0 > x1)
600 return 1;
601 l--;
602 }
603
604 return 0;
605}
606
607/*
608 * Extension.
609 */
610
611/* Sign-extend the number represented by XVAL and XLEN into VAL,
612 starting at OFFSET. Return the number of blocks in VAL. Both XVAL
613 and VAL have PRECISION bits. */
614unsigned int
615wi::sext_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
616 unsigned int xlen, unsigned int precision, unsigned int offset)
617{
618 unsigned int len = offset / HOST_BITS_PER_WIDE_INT64;
619 /* Extending beyond the precision is a no-op. If we have only stored
620 OFFSET bits or fewer, the rest are already signs. */
621 if (offset >= precision || len >= xlen)
622 {
623 for (unsigned i = 0; i < xlen; ++i)
624 val[i] = xval[i];
625 return xlen;
626 }
627 unsigned int suboffset = offset % HOST_BITS_PER_WIDE_INT64;
628 for (unsigned int i = 0; i < len; i++)
629 val[i] = xval[i];
630 if (suboffset > 0)
631 {
632 val[len] = sext_hwi (xval[len], suboffset);
633 len += 1;
634 }
635 return canonize (val, len, precision);
636}
637
638/* Zero-extend the number represented by XVAL and XLEN into VAL,
639 starting at OFFSET. Return the number of blocks in VAL. Both XVAL
640 and VAL have PRECISION bits. */
641unsigned int
642wi::zext_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
643 unsigned int xlen, unsigned int precision, unsigned int offset)
644{
645 unsigned int len = offset / HOST_BITS_PER_WIDE_INT64;
646 /* Extending beyond the precision is a no-op. If we have only stored
647 OFFSET bits or fewer, and the upper stored bit is zero, then there
648 is nothing to do. */
649 if (offset >= precision || (len >= xlen && xval[xlen - 1] >= 0))
650 {
651 for (unsigned i = 0; i < xlen; ++i)
652 val[i] = xval[i];
653 return xlen;
654 }
655 unsigned int suboffset = offset % HOST_BITS_PER_WIDE_INT64;
656 for (unsigned int i = 0; i < len; i++)
657 val[i] = i < xlen ? xval[i] : -1;
658 if (suboffset > 0)
659 val[len] = zext_hwi (len < xlen ? xval[len] : -1, suboffset);
660 else
661 val[len] = 0;
662 return canonize (val, len + 1, precision);
663}
664
665/*
666 * Masking, inserting, shifting, rotating.
667 */
668
669/* Insert WIDTH bits from Y into X starting at START. */
670wide_int
671wi::insert (const wide_int &x, const wide_int &y, unsigned int start,
672 unsigned int width)
673{
674 wide_int result;
675 wide_int mask;
676 wide_int tmp;
677
678 unsigned int precision = x.get_precision ();
679 if (start >= precision)
680 return x;
681
682 gcc_checking_assert (precision >= width)((void)(!(precision >= width) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 682, __FUNCTION__), 0 : 0))
;
683
684 if (start + width >= precision)
685 width = precision - start;
686
687 mask = wi::shifted_mask (start, width, false, precision);
688 tmp = wi::lshift (wide_int::from (y, precision, UNSIGNED), start);
689 result = tmp & mask;
690
691 tmp = wi::bit_and_not (x, mask);
692 result = result | tmp;
693
694 return result;
695}
696
697/* Copy the number represented by XVAL and XLEN into VAL, setting bit BIT.
698 Return the number of blocks in VAL. Both XVAL and VAL have PRECISION
699 bits. */
700unsigned int
701wi::set_bit_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
702 unsigned int xlen, unsigned int precision, unsigned int bit)
703{
704 unsigned int block = bit / HOST_BITS_PER_WIDE_INT64;
705 unsigned int subbit = bit % HOST_BITS_PER_WIDE_INT64;
706
707 if (block + 1 >= xlen)
708 {
709 /* The operation either affects the last current block or needs
710 a new block. */
711 unsigned int len = block + 1;
712 for (unsigned int i = 0; i < len; i++)
713 val[i] = safe_uhwi (xval, xlen, i);
714 val[block] |= HOST_WIDE_INT_1U1UL << subbit;
715
716 /* If the bit we just set is at the msb of the block, make sure
717 that any higher bits are zeros. */
718 if (bit + 1 < precision && subbit == HOST_BITS_PER_WIDE_INT64 - 1)
719 {
720 val[len++] = 0;
721 return len;
722 }
723 return canonize (val, len, precision);
724 }
725 else
726 {
727 for (unsigned int i = 0; i < xlen; i++)
728 val[i] = xval[i];
729 val[block] |= HOST_WIDE_INT_1U1UL << subbit;
730 return canonize (val, xlen, precision);
731 }
732}
733
734/* bswap THIS. */
735wide_int
736wide_int_storage::bswap () const
737{
738 wide_int result = wide_int::create (precision);
739 unsigned int i, s;
740 unsigned int len = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
741 unsigned int xlen = get_len ();
742 const HOST_WIDE_INTlong *xval = get_val ();
743 HOST_WIDE_INTlong *val = result.write_val ();
744
745 /* This is not a well defined operation if the precision is not a
746 multiple of 8. */
747 gcc_assert ((precision & 0x7) == 0)((void)(!((precision & 0x7) == 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 747, __FUNCTION__), 0 : 0))
;
748
749 for (i = 0; i < len; i++)
750 val[i] = 0;
751
752 /* Only swap the bytes that are not the padding. */
753 for (s = 0; s < precision; s += 8)
754 {
755 unsigned int d = precision - s - 8;
756 unsigned HOST_WIDE_INTlong byte;
757
758 unsigned int block = s / HOST_BITS_PER_WIDE_INT64;
759 unsigned int offset = s & (HOST_BITS_PER_WIDE_INT64 - 1);
760
761 byte = (safe_uhwi (xval, xlen, block) >> offset) & 0xff;
762
763 block = d / HOST_BITS_PER_WIDE_INT64;
764 offset = d & (HOST_BITS_PER_WIDE_INT64 - 1);
765
766 val[block] |= byte << offset;
767 }
768
769 result.set_len (canonize (val, len, precision));
770 return result;
771}
772
773/* Fill VAL with a mask where the lower WIDTH bits are ones and the bits
774 above that up to PREC are zeros. The result is inverted if NEGATE
775 is true. Return the number of blocks in VAL. */
776unsigned int
777wi::mask (HOST_WIDE_INTlong *val, unsigned int width, bool negate,
778 unsigned int prec)
779{
780 if (width >= prec)
781 {
782 val[0] = negate ? 0 : -1;
783 return 1;
784 }
785 else if (width == 0)
786 {
787 val[0] = negate ? -1 : 0;
788 return 1;
789 }
790
791 unsigned int i = 0;
792 while (i < width / HOST_BITS_PER_WIDE_INT64)
793 val[i++] = negate ? 0 : -1;
794
795 unsigned int shift = width & (HOST_BITS_PER_WIDE_INT64 - 1);
796 if (shift != 0)
797 {
798 HOST_WIDE_INTlong last = (HOST_WIDE_INT_1U1UL << shift) - 1;
799 val[i++] = negate ? ~last : last;
800 }
801 else
802 val[i++] = negate ? -1 : 0;
803
804 return i;
805}
806
807/* Fill VAL with a mask where the lower START bits are zeros, the next WIDTH
808 bits are ones, and the bits above that up to PREC are zeros. The result
809 is inverted if NEGATE is true. Return the number of blocks in VAL. */
810unsigned int
811wi::shifted_mask (HOST_WIDE_INTlong *val, unsigned int start, unsigned int width,
812 bool negate, unsigned int prec)
813{
814 if (start >= prec || width == 0)
815 {
816 val[0] = negate ? -1 : 0;
817 return 1;
818 }
819
820 if (width > prec - start)
821 width = prec - start;
822 unsigned int end = start + width;
823
824 unsigned int i = 0;
825 while (i < start / HOST_BITS_PER_WIDE_INT64)
826 val[i++] = negate ? -1 : 0;
827
828 unsigned int shift = start & (HOST_BITS_PER_WIDE_INT64 - 1);
829 if (shift)
830 {
831 HOST_WIDE_INTlong block = (HOST_WIDE_INT_1U1UL << shift) - 1;
832 shift += width;
833 if (shift < HOST_BITS_PER_WIDE_INT64)
834 {
835 /* case 000111000 */
836 block = (HOST_WIDE_INT_1U1UL << shift) - block - 1;
837 val[i++] = negate ? ~block : block;
838 return i;
839 }
840 else
841 /* ...111000 */
842 val[i++] = negate ? block : ~block;
843 }
844
845 while (i < end / HOST_BITS_PER_WIDE_INT64)
846 /* 1111111 */
847 val[i++] = negate ? 0 : -1;
848
849 shift = end & (HOST_BITS_PER_WIDE_INT64 - 1);
850 if (shift != 0)
851 {
852 /* 000011111 */
853 HOST_WIDE_INTlong block = (HOST_WIDE_INT_1U1UL << shift) - 1;
854 val[i++] = negate ? ~block : block;
855 }
856 else if (end < prec)
857 val[i++] = negate ? -1 : 0;
858
859 return i;
860}
861
862/*
863 * logical operations.
864 */
865
866/* Set VAL to OP0 & OP1. Return the number of blocks used. */
867unsigned int
868wi::and_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
869 unsigned int op0len, const HOST_WIDE_INTlong *op1,
870 unsigned int op1len, unsigned int prec)
871{
872 int l0 = op0len - 1;
873 int l1 = op1len - 1;
874 bool need_canon = true;
875
876 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
877 if (l0 > l1)
878 {
879 HOST_WIDE_INTlong op1mask = -top_bit_of (op1, op1len, prec);
880 if (op1mask == 0)
881 {
882 l0 = l1;
883 len = l1 + 1;
884 }
885 else
886 {
887 need_canon = false;
888 while (l0 > l1)
889 {
890 val[l0] = op0[l0];
891 l0--;
892 }
893 }
894 }
895 else if (l1 > l0)
896 {
897 HOST_WIDE_INTlong op0mask = -top_bit_of (op0, op0len, prec);
898 if (op0mask == 0)
899 len = l0 + 1;
900 else
901 {
902 need_canon = false;
903 while (l1 > l0)
904 {
905 val[l1] = op1[l1];
906 l1--;
907 }
908 }
909 }
910
911 while (l0 >= 0)
912 {
913 val[l0] = op0[l0] & op1[l0];
914 l0--;
915 }
916
917 if (need_canon)
918 len = canonize (val, len, prec);
919
920 return len;
921}
922
923/* Set VAL to OP0 & ~OP1. Return the number of blocks used. */
924unsigned int
925wi::and_not_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
926 unsigned int op0len, const HOST_WIDE_INTlong *op1,
927 unsigned int op1len, unsigned int prec)
928{
929 wide_int result;
930 int l0 = op0len - 1;
931 int l1 = op1len - 1;
932 bool need_canon = true;
933
934 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
935 if (l0 > l1)
936 {
937 HOST_WIDE_INTlong op1mask = -top_bit_of (op1, op1len, prec);
938 if (op1mask != 0)
939 {
940 l0 = l1;
941 len = l1 + 1;
942 }
943 else
944 {
945 need_canon = false;
946 while (l0 > l1)
947 {
948 val[l0] = op0[l0];
949 l0--;
950 }
951 }
952 }
953 else if (l1 > l0)
954 {
955 HOST_WIDE_INTlong op0mask = -top_bit_of (op0, op0len, prec);
956 if (op0mask == 0)
957 len = l0 + 1;
958 else
959 {
960 need_canon = false;
961 while (l1 > l0)
962 {
963 val[l1] = ~op1[l1];
964 l1--;
965 }
966 }
967 }
968
969 while (l0 >= 0)
970 {
971 val[l0] = op0[l0] & ~op1[l0];
972 l0--;
973 }
974
975 if (need_canon)
976 len = canonize (val, len, prec);
977
978 return len;
979}
980
981/* Set VAL to OP0 | OP1. Return the number of blocks used. */
982unsigned int
983wi::or_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
984 unsigned int op0len, const HOST_WIDE_INTlong *op1,
985 unsigned int op1len, unsigned int prec)
986{
987 wide_int result;
988 int l0 = op0len - 1;
989 int l1 = op1len - 1;
990 bool need_canon = true;
991
992 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
993 if (l0 > l1)
994 {
995 HOST_WIDE_INTlong op1mask = -top_bit_of (op1, op1len, prec);
996 if (op1mask != 0)
997 {
998 l0 = l1;
999 len = l1 + 1;
1000 }
1001 else
1002 {
1003 need_canon = false;
1004 while (l0 > l1)
1005 {
1006 val[l0] = op0[l0];
1007 l0--;
1008 }
1009 }
1010 }
1011 else if (l1 > l0)
1012 {
1013 HOST_WIDE_INTlong op0mask = -top_bit_of (op0, op0len, prec);
1014 if (op0mask != 0)
1015 len = l0 + 1;
1016 else
1017 {
1018 need_canon = false;
1019 while (l1 > l0)
1020 {
1021 val[l1] = op1[l1];
1022 l1--;
1023 }
1024 }
1025 }
1026
1027 while (l0 >= 0)
1028 {
1029 val[l0] = op0[l0] | op1[l0];
1030 l0--;
1031 }
1032
1033 if (need_canon)
1034 len = canonize (val, len, prec);
1035
1036 return len;
1037}
1038
1039/* Set VAL to OP0 | ~OP1. Return the number of blocks used. */
1040unsigned int
1041wi::or_not_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
1042 unsigned int op0len, const HOST_WIDE_INTlong *op1,
1043 unsigned int op1len, unsigned int prec)
1044{
1045 wide_int result;
1046 int l0 = op0len - 1;
1047 int l1 = op1len - 1;
1048 bool need_canon = true;
1049
1050 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
1051 if (l0 > l1)
1052 {
1053 HOST_WIDE_INTlong op1mask = -top_bit_of (op1, op1len, prec);
1054 if (op1mask == 0)
1055 {
1056 l0 = l1;
1057 len = l1 + 1;
1058 }
1059 else
1060 {
1061 need_canon = false;
1062 while (l0 > l1)
1063 {
1064 val[l0] = op0[l0];
1065 l0--;
1066 }
1067 }
1068 }
1069 else if (l1 > l0)
1070 {
1071 HOST_WIDE_INTlong op0mask = -top_bit_of (op0, op0len, prec);
1072 if (op0mask != 0)
1073 len = l0 + 1;
1074 else
1075 {
1076 need_canon = false;
1077 while (l1 > l0)
1078 {
1079 val[l1] = ~op1[l1];
1080 l1--;
1081 }
1082 }
1083 }
1084
1085 while (l0 >= 0)
1086 {
1087 val[l0] = op0[l0] | ~op1[l0];
1088 l0--;
1089 }
1090
1091 if (need_canon)
1092 len = canonize (val, len, prec);
1093
1094 return len;
1095}
1096
1097/* Set VAL to OP0 ^ OP1. Return the number of blocks used. */
1098unsigned int
1099wi::xor_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
1100 unsigned int op0len, const HOST_WIDE_INTlong *op1,
1101 unsigned int op1len, unsigned int prec)
1102{
1103 wide_int result;
1104 int l0 = op0len - 1;
1105 int l1 = op1len - 1;
1106
1107 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
1108 if (l0 > l1)
1109 {
1110 HOST_WIDE_INTlong op1mask = -top_bit_of (op1, op1len, prec);
1111 while (l0 > l1)
1112 {
1113 val[l0] = op0[l0] ^ op1mask;
1114 l0--;
1115 }
1116 }
1117
1118 if (l1 > l0)
1119 {
1120 HOST_WIDE_INTlong op0mask = -top_bit_of (op0, op0len, prec);
1121 while (l1 > l0)
1122 {
1123 val[l1] = op0mask ^ op1[l1];
1124 l1--;
1125 }
1126 }
1127
1128 while (l0 >= 0)
1129 {
1130 val[l0] = op0[l0] ^ op1[l0];
1131 l0--;
1132 }
1133
1134 return canonize (val, len, prec);
1135}
1136
1137/*
1138 * math
1139 */
1140
1141/* Set VAL to OP0 + OP1. If OVERFLOW is nonnull, record in *OVERFLOW
1142 whether the result overflows when OP0 and OP1 are treated as having
1143 signedness SGN. Return the number of blocks in VAL. */
1144unsigned int
1145wi::add_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
1146 unsigned int op0len, const HOST_WIDE_INTlong *op1,
1147 unsigned int op1len, unsigned int prec,
1148 signop sgn, wi::overflow_type *overflow)
1149{
1150 unsigned HOST_WIDE_INTlong o0 = 0;
1151 unsigned HOST_WIDE_INTlong o1 = 0;
1152 unsigned HOST_WIDE_INTlong x = 0;
1153 unsigned HOST_WIDE_INTlong carry = 0;
1154 unsigned HOST_WIDE_INTlong old_carry = 0;
1155 unsigned HOST_WIDE_INTlong mask0, mask1;
1156 unsigned int i;
1157
1158 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
1159 mask0 = -top_bit_of (op0, op0len, prec);
1160 mask1 = -top_bit_of (op1, op1len, prec);
1161 /* Add all of the explicitly defined elements. */
1162
1163 for (i = 0; i < len; i++)
1164 {
1165 o0 = i < op0len ? (unsigned HOST_WIDE_INTlong) op0[i] : mask0;
1166 o1 = i < op1len ? (unsigned HOST_WIDE_INTlong) op1[i] : mask1;
1167 x = o0 + o1 + carry;
1168 val[i] = x;
1169 old_carry = carry;
1170 carry = carry == 0 ? x < o0 : x <= o0;
1171 }
1172
1173 if (len * HOST_BITS_PER_WIDE_INT64 < prec)
1174 {
1175 val[len] = mask0 + mask1 + carry;
1176 len++;
1177 if (overflow)
1178 *overflow
1179 = (sgn == UNSIGNED && carry) ? wi::OVF_OVERFLOW : wi::OVF_NONE;
1180 }
1181 else if (overflow)
1182 {
1183 unsigned int shift = -prec % HOST_BITS_PER_WIDE_INT64;
1184 if (sgn == SIGNED)
1185 {
1186 unsigned HOST_WIDE_INTlong x = (val[len - 1] ^ o0) & (val[len - 1] ^ o1);
1187 if ((HOST_WIDE_INTlong) (x << shift) < 0)
1188 {
1189 if (o0 > (unsigned HOST_WIDE_INTlong) val[len - 1])
1190 *overflow = wi::OVF_UNDERFLOW;
1191 else if (o0 < (unsigned HOST_WIDE_INTlong) val[len - 1])
1192 *overflow = wi::OVF_OVERFLOW;
1193 else
1194 *overflow = wi::OVF_NONE;
1195 }
1196 else
1197 *overflow = wi::OVF_NONE;
1198 }
1199 else
1200 {
1201 /* Put the MSB of X and O0 and in the top of the HWI. */
1202 x <<= shift;
1203 o0 <<= shift;
1204 if (old_carry)
1205 *overflow = (x <= o0) ? wi::OVF_OVERFLOW : wi::OVF_NONE;
1206 else
1207 *overflow = (x < o0) ? wi::OVF_OVERFLOW : wi::OVF_NONE;
1208 }
1209 }
1210
1211 return canonize (val, len, prec);
1212}
1213
1214/* Subroutines of the multiplication and division operations. Unpack
1215 the first IN_LEN HOST_WIDE_INTs in INPUT into 2 * IN_LEN
1216 HOST_HALF_WIDE_INTs of RESULT. The rest of RESULT is filled by
1217 uncompressing the top bit of INPUT[IN_LEN - 1]. */
1218static void
1219wi_unpack (unsigned HOST_HALF_WIDE_INTint *result, const HOST_WIDE_INTlong *input,
1220 unsigned int in_len, unsigned int out_len,
1221 unsigned int prec, signop sgn)
1222{
1223 unsigned int i;
1224 unsigned int j = 0;
1225 unsigned int small_prec = prec & (HOST_BITS_PER_WIDE_INT64 - 1);
1226 unsigned int blocks_needed = BLOCKS_NEEDED (prec)(prec ? (((prec) + 64 - 1) / 64) : 1);
1227 HOST_WIDE_INTlong mask;
1228
1229 if (sgn == SIGNED)
1230 {
1231 mask = -top_bit_of ((const HOST_WIDE_INTlong *) input, in_len, prec);
1232 mask &= HALF_INT_MASK((1L << 32) - 1);
1233 }
1234 else
1235 mask = 0;
1236
1237 for (i = 0; i < blocks_needed - 1; i++)
1238 {
1239 HOST_WIDE_INTlong x = safe_uhwi (input, in_len, i);
1240 result[j++] = x;
1241 result[j++] = x >> HOST_BITS_PER_HALF_WIDE_INT32;
1242 }
1243
1244 HOST_WIDE_INTlong x = safe_uhwi (input, in_len, i);
1245 if (small_prec)
1246 {
1247 if (sgn == SIGNED)
1248 x = sext_hwi (x, small_prec);
1249 else
1250 x = zext_hwi (x, small_prec);
1251 }
1252 result[j++] = x;
1253 result[j++] = x >> HOST_BITS_PER_HALF_WIDE_INT32;
1254
1255 /* Smear the sign bit. */
1256 while (j < out_len)
1257 result[j++] = mask;
1258}
1259
1260/* The inverse of wi_unpack. IN_LEN is the number of input
1261 blocks and PRECISION is the precision of the result. Return the
1262 number of blocks in the canonicalized result. */
1263static unsigned int
1264wi_pack (HOST_WIDE_INTlong *result,
1265 const unsigned HOST_HALF_WIDE_INTint *input,
1266 unsigned int in_len, unsigned int precision)
1267{
1268 unsigned int i = 0;
1269 unsigned int j = 0;
1270 unsigned int blocks_needed = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
1271
1272 while (i + 1 < in_len)
1273 {
1274 result[j++] = ((unsigned HOST_WIDE_INTlong) input[i]
1275 | ((unsigned HOST_WIDE_INTlong) input[i + 1]
1276 << HOST_BITS_PER_HALF_WIDE_INT32));
1277 i += 2;
1278 }
1279
1280 /* Handle the case where in_len is odd. For this we zero extend. */
1281 if (in_len & 1)
1282 result[j++] = (unsigned HOST_WIDE_INTlong) input[i];
1283 else if (j < blocks_needed)
1284 result[j++] = 0;
1285 return canonize (result, j, precision);
1286}
1287
1288/* Multiply Op1 by Op2. If HIGH is set, only the upper half of the
1289 result is returned.
1290
1291 If HIGH is not set, throw away the upper half after the check is
1292 made to see if it overflows. Unfortunately there is no better way
1293 to check for overflow than to do this. If OVERFLOW is nonnull,
1294 record in *OVERFLOW whether the result overflowed. SGN controls
1295 the signedness and is used to check overflow or if HIGH is set.
1296
1297 NOTE: Overflow type for signed overflow is not yet implemented. */
1298unsigned int
1299wi::mul_internal (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op1val,
1300 unsigned int op1len, const HOST_WIDE_INTlong *op2val,
1301 unsigned int op2len, unsigned int prec, signop sgn,
1302 wi::overflow_type *overflow, bool high)
1303{
1304 unsigned HOST_WIDE_INTlong o0, o1, k, t;
1305 unsigned int i;
1306 unsigned int j;
1307 unsigned int blocks_needed = BLOCKS_NEEDED (prec)(prec ? (((prec) + 64 - 1) / 64) : 1);
1308 unsigned int half_blocks_needed = blocks_needed * 2;
1309 /* The sizes here are scaled to support a 2x largest mode by 2x
1310 largest mode yielding a 4x largest mode result. This is what is
1311 needed by vpn. */
1312
1313 unsigned HOST_HALF_WIDE_INTint
1314 u[4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1315 unsigned HOST_HALF_WIDE_INTint
1316 v[4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1317 /* The '2' in 'R' is because we are internally doing a full
1318 multiply. */
1319 unsigned HOST_HALF_WIDE_INTint
1320 r[2 * 4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1321 HOST_WIDE_INTlong mask = ((HOST_WIDE_INTlong)1 << HOST_BITS_PER_HALF_WIDE_INT32) - 1;
1322
1323 /* If the top level routine did not really pass in an overflow, then
1324 just make sure that we never attempt to set it. */
1325 bool needs_overflow = (overflow != 0);
1326 if (needs_overflow)
1327 *overflow = wi::OVF_NONE;
1328
1329 wide_int_ref op1 = wi::storage_ref (op1val, op1len, prec);
1330 wide_int_ref op2 = wi::storage_ref (op2val, op2len, prec);
1331
1332 /* This is a surprisingly common case, so do it first. */
1333 if (op1 == 0 || op2 == 0)
1334 {
1335 val[0] = 0;
1336 return 1;
1337 }
1338
1339#ifdef umul_ppmm
1340 if (sgn == UNSIGNED)
1341 {
1342 /* If the inputs are single HWIs and the output has room for at
1343 least two HWIs, we can use umul_ppmm directly. */
1344 if (prec >= HOST_BITS_PER_WIDE_INT64 * 2
1345 && wi::fits_uhwi_p (op1)
1346 && wi::fits_uhwi_p (op2))
1347 {
1348 /* This case never overflows. */
1349 if (high)
1350 {
1351 val[0] = 0;
1352 return 1;
1353 }
1354 umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ());
1355 if (val[1] < 0 && prec > HOST_BITS_PER_WIDE_INT64 * 2)
1356 {
1357 val[2] = 0;
1358 return 3;
1359 }
1360 return 1 + (val[1] != 0 || val[0] < 0);
1361 }
1362 /* Likewise if the output is a full single HWI, except that the
1363 upper HWI of the result is only used for determining overflow.
1364 (We handle this case inline when overflow isn't needed.) */
1365 else if (prec == HOST_BITS_PER_WIDE_INT64)
1366 {
1367 unsigned HOST_WIDE_INTlong upper;
1368 umul_ppmm (upper, val[0], op1.ulow (), op2.ulow ());
1369 if (needs_overflow)
1370 /* Unsigned overflow can only be +OVERFLOW. */
1371 *overflow = (upper != 0) ? wi::OVF_OVERFLOW : wi::OVF_NONE;
1372 if (high)
1373 val[0] = upper;
1374 return 1;
1375 }
1376 }
1377#endif
1378
1379 /* Handle multiplications by 1. */
1380 if (op1 == 1)
1381 {
1382 if (high)
1383 {
1384 val[0] = wi::neg_p (op2, sgn) ? -1 : 0;
1385 return 1;
1386 }
1387 for (i = 0; i < op2len; i++)
1388 val[i] = op2val[i];
1389 return op2len;
1390 }
1391 if (op2 == 1)
1392 {
1393 if (high)
1394 {
1395 val[0] = wi::neg_p (op1, sgn) ? -1 : 0;
1396 return 1;
1397 }
1398 for (i = 0; i < op1len; i++)
1399 val[i] = op1val[i];
1400 return op1len;
1401 }
1402
1403 /* If we need to check for overflow, we can only do half wide
1404 multiplies quickly because we need to look at the top bits to
1405 check for the overflow. */
1406 if ((high || needs_overflow)
1407 && (prec <= HOST_BITS_PER_HALF_WIDE_INT32))
1408 {
1409 unsigned HOST_WIDE_INTlong r;
1410
1411 if (sgn == SIGNED)
1412 {
1413 o0 = op1.to_shwi ();
1414 o1 = op2.to_shwi ();
1415 }
1416 else
1417 {
1418 o0 = op1.to_uhwi ();
1419 o1 = op2.to_uhwi ();
1420 }
1421
1422 r = o0 * o1;
1423 if (needs_overflow)
1424 {
1425 if (sgn == SIGNED)
1426 {
1427 if ((HOST_WIDE_INTlong) r != sext_hwi (r, prec))
1428 /* FIXME: Signed overflow type is not implemented yet. */
1429 *overflow = OVF_UNKNOWN;
1430 }
1431 else
1432 {
1433 if ((r >> prec) != 0)
1434 /* Unsigned overflow can only be +OVERFLOW. */
1435 *overflow = OVF_OVERFLOW;
1436 }
1437 }
1438 val[0] = high ? r >> prec : r;
1439 return 1;
1440 }
1441
1442 /* We do unsigned mul and then correct it. */
1443 wi_unpack (u, op1val, op1len, half_blocks_needed, prec, SIGNED);
1444 wi_unpack (v, op2val, op2len, half_blocks_needed, prec, SIGNED);
1445
1446 /* The 2 is for a full mult. */
1447 memset (r, 0, half_blocks_needed * 2
1448 * HOST_BITS_PER_HALF_WIDE_INT32 / CHAR_BIT8);
1449
1450 for (j = 0; j < half_blocks_needed; j++)
1451 {
1452 k = 0;
1453 for (i = 0; i < half_blocks_needed; i++)
1454 {
1455 t = ((unsigned HOST_WIDE_INTlong)u[i] * (unsigned HOST_WIDE_INTlong)v[j]
1456 + r[i + j] + k);
1457 r[i + j] = t & HALF_INT_MASK((1L << 32) - 1);
1458 k = t >> HOST_BITS_PER_HALF_WIDE_INT32;
1459 }
1460 r[j + half_blocks_needed] = k;
1461 }
1462
1463 /* We did unsigned math above. For signed we must adjust the
1464 product (assuming we need to see that). */
1465 if (sgn == SIGNED && (high || needs_overflow))
1466 {
1467 unsigned HOST_WIDE_INTlong b;
1468 if (wi::neg_p (op1))
1469 {
1470 b = 0;
1471 for (i = 0; i < half_blocks_needed; i++)
1472 {
1473 t = (unsigned HOST_WIDE_INTlong)r[i + half_blocks_needed]
1474 - (unsigned HOST_WIDE_INTlong)v[i] - b;
1475 r[i + half_blocks_needed] = t & HALF_INT_MASK((1L << 32) - 1);
1476 b = t >> (HOST_BITS_PER_WIDE_INT64 - 1);
1477 }
1478 }
1479 if (wi::neg_p (op2))
1480 {
1481 b = 0;
1482 for (i = 0; i < half_blocks_needed; i++)
1483 {
1484 t = (unsigned HOST_WIDE_INTlong)r[i + half_blocks_needed]
1485 - (unsigned HOST_WIDE_INTlong)u[i] - b;
1486 r[i + half_blocks_needed] = t & HALF_INT_MASK((1L << 32) - 1);
1487 b = t >> (HOST_BITS_PER_WIDE_INT64 - 1);
1488 }
1489 }
1490 }
1491
1492 if (needs_overflow)
1493 {
1494 HOST_WIDE_INTlong top;
1495
1496 /* For unsigned, overflow is true if any of the top bits are set.
1497 For signed, overflow is true if any of the top bits are not equal
1498 to the sign bit. */
1499 if (sgn == UNSIGNED)
1500 top = 0;
1501 else
1502 {
1503 top = r[(half_blocks_needed) - 1];
1504 top = SIGN_MASK (top << (HOST_BITS_PER_WIDE_INT / 2))((long) (top << (64 / 2)) < 0 ? -1 : 0);
1505 top &= mask;
1506 }
1507
1508 for (i = half_blocks_needed; i < half_blocks_needed * 2; i++)
1509 if (((HOST_WIDE_INTlong)(r[i] & mask)) != top)
1510 /* FIXME: Signed overflow type is not implemented yet. */
1511 *overflow = (sgn == UNSIGNED) ? wi::OVF_OVERFLOW : wi::OVF_UNKNOWN;
1512 }
1513
1514 int r_offset = high ? half_blocks_needed : 0;
1515 return wi_pack (val, &r[r_offset], half_blocks_needed, prec);
1516}
1517
1518/* Compute the population count of X. */
1519int
1520wi::popcount (const wide_int_ref &x)
1521{
1522 unsigned int i;
1523 int count;
1524
1525 /* The high order block is special if it is the last block and the
1526 precision is not an even multiple of HOST_BITS_PER_WIDE_INT. We
1527 have to clear out any ones above the precision before doing
1528 popcount on this block. */
1529 count = x.precision - x.len * HOST_BITS_PER_WIDE_INT64;
1530 unsigned int stop = x.len;
1531 if (count < 0)
1532 {
1533 count = popcount_hwi (x.uhigh () << -count);
1534 stop -= 1;
1535 }
1536 else
1537 {
1538 if (x.sign_mask () >= 0)
1539 count = 0;
1540 }
1541
1542 for (i = 0; i < stop; ++i)
1543 count += popcount_hwi (x.val[i]);
1544
1545 return count;
1546}
1547
1548/* Set VAL to OP0 - OP1. If OVERFLOW is nonnull, record in *OVERFLOW
1549 whether the result overflows when OP0 and OP1 are treated as having
1550 signedness SGN. Return the number of blocks in VAL. */
1551unsigned int
1552wi::sub_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *op0,
1553 unsigned int op0len, const HOST_WIDE_INTlong *op1,
1554 unsigned int op1len, unsigned int prec,
1555 signop sgn, wi::overflow_type *overflow)
1556{
1557 unsigned HOST_WIDE_INTlong o0 = 0;
1558 unsigned HOST_WIDE_INTlong o1 = 0;
1559 unsigned HOST_WIDE_INTlong x = 0;
1560 /* We implement subtraction as an in place negate and add. Negation
1561 is just inversion and add 1, so we can do the add of 1 by just
1562 starting the borrow in of the first element at 1. */
1563 unsigned HOST_WIDE_INTlong borrow = 0;
1564 unsigned HOST_WIDE_INTlong old_borrow = 0;
1565
1566 unsigned HOST_WIDE_INTlong mask0, mask1;
1567 unsigned int i;
1568
1569 unsigned int len = MAX (op0len, op1len)((op0len) > (op1len) ? (op0len) : (op1len));
1570 mask0 = -top_bit_of (op0, op0len, prec);
1571 mask1 = -top_bit_of (op1, op1len, prec);
1572
1573 /* Subtract all of the explicitly defined elements. */
1574 for (i = 0; i < len; i++)
1575 {
1576 o0 = i < op0len ? (unsigned HOST_WIDE_INTlong)op0[i] : mask0;
1577 o1 = i < op1len ? (unsigned HOST_WIDE_INTlong)op1[i] : mask1;
1578 x = o0 - o1 - borrow;
1579 val[i] = x;
1580 old_borrow = borrow;
1581 borrow = borrow == 0 ? o0 < o1 : o0 <= o1;
1582 }
1583
1584 if (len * HOST_BITS_PER_WIDE_INT64 < prec)
1585 {
1586 val[len] = mask0 - mask1 - borrow;
1587 len++;
1588 if (overflow)
1589 *overflow = (sgn == UNSIGNED && borrow) ? OVF_UNDERFLOW : OVF_NONE;
1590 }
1591 else if (overflow)
1592 {
1593 unsigned int shift = -prec % HOST_BITS_PER_WIDE_INT64;
1594 if (sgn == SIGNED)
1595 {
1596 unsigned HOST_WIDE_INTlong x = (o0 ^ o1) & (val[len - 1] ^ o0);
1597 if ((HOST_WIDE_INTlong) (x << shift) < 0)
1598 {
1599 if (o0 > o1)
1600 *overflow = OVF_UNDERFLOW;
1601 else if (o0 < o1)
1602 *overflow = OVF_OVERFLOW;
1603 else
1604 *overflow = OVF_NONE;
1605 }
1606 else
1607 *overflow = OVF_NONE;
1608 }
1609 else
1610 {
1611 /* Put the MSB of X and O0 and in the top of the HWI. */
1612 x <<= shift;
1613 o0 <<= shift;
1614 if (old_borrow)
1615 *overflow = (x >= o0) ? OVF_UNDERFLOW : OVF_NONE;
1616 else
1617 *overflow = (x > o0) ? OVF_UNDERFLOW : OVF_NONE;
1618 }
1619 }
1620
1621 return canonize (val, len, prec);
1622}
1623
1624
1625/*
1626 * Division and Mod
1627 */
1628
1629/* Compute B_QUOTIENT and B_REMAINDER from B_DIVIDEND/B_DIVISOR. The
1630 algorithm is a small modification of the algorithm in Hacker's
1631 Delight by Warren, which itself is a small modification of Knuth's
1632 algorithm. M is the number of significant elements of U however
1633 there needs to be at least one extra element of B_DIVIDEND
1634 allocated, N is the number of elements of B_DIVISOR. */
1635static void
1636divmod_internal_2 (unsigned HOST_HALF_WIDE_INTint *b_quotient,
1637 unsigned HOST_HALF_WIDE_INTint *b_remainder,
1638 unsigned HOST_HALF_WIDE_INTint *b_dividend,
1639 unsigned HOST_HALF_WIDE_INTint *b_divisor,
1640 int m, int n)
1641{
1642 /* The "digits" are a HOST_HALF_WIDE_INT which the size of half of a
1643 HOST_WIDE_INT and stored in the lower bits of each word. This
1644 algorithm should work properly on both 32 and 64 bit
1645 machines. */
1646 unsigned HOST_WIDE_INTlong b
1647 = (unsigned HOST_WIDE_INTlong)1 << HOST_BITS_PER_HALF_WIDE_INT32;
1648 unsigned HOST_WIDE_INTlong qhat; /* Estimate of quotient digit. */
1649 unsigned HOST_WIDE_INTlong rhat; /* A remainder. */
1650 unsigned HOST_WIDE_INTlong p; /* Product of two digits. */
1651 HOST_WIDE_INTlong t, k;
1652 int i, j, s;
1653
1654 /* Single digit divisor. */
1655 if (n == 1)
1656 {
1657 k = 0;
1658 for (j = m - 1; j >= 0; j--)
1659 {
1660 b_quotient[j] = (k * b + b_dividend[j])/b_divisor[0];
1661 k = ((k * b + b_dividend[j])
1662 - ((unsigned HOST_WIDE_INTlong)b_quotient[j]
1663 * (unsigned HOST_WIDE_INTlong)b_divisor[0]));
1664 }
1665 b_remainder[0] = k;
1666 return;
1667 }
1668
1669 s = clz_hwi (b_divisor[n-1]) - HOST_BITS_PER_HALF_WIDE_INT32; /* CHECK clz */
1670
1671 if (s)
1672 {
1673 /* Normalize B_DIVIDEND and B_DIVISOR. Unlike the published
1674 algorithm, we can overwrite b_dividend and b_divisor, so we do
1675 that. */
1676 for (i = n - 1; i > 0; i--)
1677 b_divisor[i] = (b_divisor[i] << s)
1678 | (b_divisor[i-1] >> (HOST_BITS_PER_HALF_WIDE_INT32 - s));
1679 b_divisor[0] = b_divisor[0] << s;
1680
1681 b_dividend[m] = b_dividend[m-1] >> (HOST_BITS_PER_HALF_WIDE_INT32 - s);
1682 for (i = m - 1; i > 0; i--)
1683 b_dividend[i] = (b_dividend[i] << s)
1684 | (b_dividend[i-1] >> (HOST_BITS_PER_HALF_WIDE_INT32 - s));
1685 b_dividend[0] = b_dividend[0] << s;
1686 }
1687
1688 /* Main loop. */
1689 for (j = m - n; j >= 0; j--)
1690 {
1691 qhat = (b_dividend[j+n] * b + b_dividend[j+n-1]) / b_divisor[n-1];
1692 rhat = (b_dividend[j+n] * b + b_dividend[j+n-1]) - qhat * b_divisor[n-1];
1693 again:
1694 if (qhat >= b || qhat * b_divisor[n-2] > b * rhat + b_dividend[j+n-2])
1695 {
1696 qhat -= 1;
1697 rhat += b_divisor[n-1];
1698 if (rhat < b)
1699 goto again;
1700 }
1701
1702 /* Multiply and subtract. */
1703 k = 0;
1704 for (i = 0; i < n; i++)
1705 {
1706 p = qhat * b_divisor[i];
1707 t = b_dividend[i+j] - k - (p & HALF_INT_MASK((1L << 32) - 1));
1708 b_dividend[i + j] = t;
1709 k = ((p >> HOST_BITS_PER_HALF_WIDE_INT32)
1710 - (t >> HOST_BITS_PER_HALF_WIDE_INT32));
1711 }
1712 t = b_dividend[j+n] - k;
1713 b_dividend[j+n] = t;
1714
1715 b_quotient[j] = qhat;
1716 if (t < 0)
1717 {
1718 b_quotient[j] -= 1;
1719 k = 0;
1720 for (i = 0; i < n; i++)
1721 {
1722 t = (HOST_WIDE_INTlong)b_dividend[i+j] + b_divisor[i] + k;
1723 b_dividend[i+j] = t;
1724 k = t >> HOST_BITS_PER_HALF_WIDE_INT32;
1725 }
1726 b_dividend[j+n] += k;
1727 }
1728 }
1729 if (s)
1730 for (i = 0; i < n; i++)
1731 b_remainder[i] = (b_dividend[i] >> s)
1732 | (b_dividend[i+1] << (HOST_BITS_PER_HALF_WIDE_INT32 - s));
1733 else
1734 for (i = 0; i < n; i++)
1735 b_remainder[i] = b_dividend[i];
1736}
1737
1738
1739/* Divide DIVIDEND by DIVISOR, which have signedness SGN, and truncate
1740 the result. If QUOTIENT is nonnull, store the value of the quotient
1741 there and return the number of blocks in it. The return value is
1742 not defined otherwise. If REMAINDER is nonnull, store the value
1743 of the remainder there and store the number of blocks in
1744 *REMAINDER_LEN. If OFLOW is not null, store in *OFLOW whether
1745 the division overflowed. */
1746unsigned int
1747wi::divmod_internal (HOST_WIDE_INTlong *quotient, unsigned int *remainder_len,
1748 HOST_WIDE_INTlong *remainder,
1749 const HOST_WIDE_INTlong *dividend_val,
1750 unsigned int dividend_len, unsigned int dividend_prec,
1751 const HOST_WIDE_INTlong *divisor_val, unsigned int divisor_len,
1752 unsigned int divisor_prec, signop sgn,
1753 wi::overflow_type *oflow)
1754{
1755 unsigned int dividend_blocks_needed = 2 * BLOCKS_NEEDED (dividend_prec)(dividend_prec ? (((dividend_prec) + 64 - 1) / 64) : 1);
5
Assuming 'dividend_prec' is not equal to 0
6
'?' condition is true
1756 unsigned int divisor_blocks_needed = 2 * BLOCKS_NEEDED (divisor_prec)(divisor_prec ? (((divisor_prec) + 64 - 1) / 64) : 1);
7
'?' condition is false
1757 unsigned HOST_HALF_WIDE_INTint
1758 b_quotient[4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1759 unsigned HOST_HALF_WIDE_INTint
1760 b_remainder[4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1761 unsigned HOST_HALF_WIDE_INTint
1762 b_dividend[(4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32) + 1];
1763 unsigned HOST_HALF_WIDE_INTint
1764 b_divisor[4 * MAX_BITSIZE_MODE_ANY_INT(64*(8)) / HOST_BITS_PER_HALF_WIDE_INT32];
1765 unsigned int m, n;
1766 bool dividend_neg = false;
1767 bool divisor_neg = false;
1768 bool overflow = false;
1769 wide_int neg_dividend, neg_divisor;
1770
1771 wide_int_ref dividend = wi::storage_ref (dividend_val, dividend_len,
1772 dividend_prec);
1773 wide_int_ref divisor = wi::storage_ref (divisor_val, divisor_len,
1774 divisor_prec);
1775 if (divisor == 0)
8
Taking false branch
1776 overflow = true;
1777
1778 /* The smallest signed number / -1 causes overflow. The dividend_len
1779 check is for speed rather than correctness. */
1780 if (sgn
8.1
'sgn' is not equal to SIGNED
8.1
'sgn' is not equal to SIGNED
8.1
'sgn' is not equal to SIGNED
== SIGNED
9
Taking false branch
1781 && dividend_len == BLOCKS_NEEDED (dividend_prec)(dividend_prec ? (((dividend_prec) + 64 - 1) / 64) : 1)
1782 && divisor == -1
1783 && wi::only_sign_bit_p (dividend))
1784 overflow = true;
1785
1786 /* Handle the overflow cases. Viewed as unsigned value, the quotient of
1787 (signed min / -1) has the same representation as the orignal dividend.
1788 We have traditionally made division by zero act as division by one,
1789 so there too we use the original dividend. */
1790 if (overflow
9.1
'overflow' is false
9.1
'overflow' is false
9.1
'overflow' is false
)
10
Taking false branch
1791 {
1792 if (remainder)
1793 {
1794 *remainder_len = 1;
1795 remainder[0] = 0;
1796 }
1797 if (oflow)
1798 *oflow = OVF_OVERFLOW;
1799 if (quotient)
1800 for (unsigned int i = 0; i < dividend_len; ++i)
1801 quotient[i] = dividend_val[i];
1802 return dividend_len;
1803 }
1804
1805 if (oflow
10.1
'oflow' is null
10.1
'oflow' is null
10.1
'oflow' is null
)
11
Taking false branch
1806 *oflow = OVF_NONE;
1807
1808 /* Do it on the host if you can. */
1809 if (sgn
11.1
'sgn' is not equal to SIGNED
11.1
'sgn' is not equal to SIGNED
11.1
'sgn' is not equal to SIGNED
== SIGNED
1810 && wi::fits_shwi_p (dividend)
1811 && wi::fits_shwi_p (divisor))
1812 {
1813 HOST_WIDE_INTlong o0 = dividend.to_shwi ();
1814 HOST_WIDE_INTlong o1 = divisor.to_shwi ();
1815
1816 if (o0 == HOST_WIDE_INT_MIN(long) (1UL << (64 - 1)) && o1 == -1)
1817 {
1818 gcc_checking_assert (dividend_prec > HOST_BITS_PER_WIDE_INT)((void)(!(dividend_prec > 64) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 1818, __FUNCTION__), 0 : 0))
;
1819 if (quotient)
1820 {
1821 quotient[0] = HOST_WIDE_INT_MIN(long) (1UL << (64 - 1));
1822 quotient[1] = 0;
1823 }
1824 if (remainder)
1825 {
1826 remainder[0] = 0;
1827 *remainder_len = 1;
1828 }
1829 return 2;
1830 }
1831 else
1832 {
1833 if (quotient)
1834 quotient[0] = o0 / o1;
1835 if (remainder)
1836 {
1837 remainder[0] = o0 % o1;
1838 *remainder_len = 1;
1839 }
1840 return 1;
1841 }
1842 }
1843
1844 if (sgn
11.2
'sgn' is equal to UNSIGNED
11.2
'sgn' is equal to UNSIGNED
11.2
'sgn' is equal to UNSIGNED
== UNSIGNED
21
Taking true branch
1845 && wi::fits_uhwi_p (dividend)
12
Calling 'fits_uhwi_p<generic_wide_int<wide_int_ref_storage<false, true>>>'
16
Returning from 'fits_uhwi_p<generic_wide_int<wide_int_ref_storage<false, true>>>'
1846 && wi::fits_uhwi_p (divisor))
17
Calling 'fits_uhwi_p<generic_wide_int<wide_int_ref_storage<false, true>>>'
20
Returning from 'fits_uhwi_p<generic_wide_int<wide_int_ref_storage<false, true>>>'
1847 {
1848 unsigned HOST_WIDE_INTlong o0 = dividend.to_uhwi ();
1849 unsigned HOST_WIDE_INTlong o1 = divisor.to_uhwi ();
22
Calling 'generic_wide_int::to_uhwi'
33
Returning from 'generic_wide_int::to_uhwi'
34
'o1' initialized to 0
1850 unsigned int quotient_len = 1;
1851
1852 if (quotient
34.1
'quotient' is null
34.1
'quotient' is null
34.1
'quotient' is null
)
35
Taking false branch
1853 {
1854 quotient[0] = o0 / o1;
1855 quotient_len = canonize_uhwi (quotient, dividend_prec);
1856 }
1857 if (remainder
35.1
'remainder' is non-null
35.1
'remainder' is non-null
35.1
'remainder' is non-null
)
36
Taking true branch
1858 {
1859 remainder[0] = o0 % o1;
37
Division by zero
1860 *remainder_len = canonize_uhwi (remainder, dividend_prec);
1861 }
1862 return quotient_len;
1863 }
1864
1865 /* Make the divisor and dividend positive and remember what we
1866 did. */
1867 if (sgn == SIGNED)
1868 {
1869 if (wi::neg_p (dividend))
1870 {
1871 neg_dividend = -dividend;
1872 dividend = neg_dividend;
1873 dividend_neg = true;
1874 }
1875 if (wi::neg_p (divisor))
1876 {
1877 neg_divisor = -divisor;
1878 divisor = neg_divisor;
1879 divisor_neg = true;
1880 }
1881 }
1882
1883 wi_unpack (b_dividend, dividend.get_val (), dividend.get_len (),
1884 dividend_blocks_needed, dividend_prec, sgn);
1885 wi_unpack (b_divisor, divisor.get_val (), divisor.get_len (),
1886 divisor_blocks_needed, divisor_prec, sgn);
1887
1888 m = dividend_blocks_needed;
1889 b_dividend[m] = 0;
1890 while (m > 1 && b_dividend[m - 1] == 0)
1891 m--;
1892
1893 n = divisor_blocks_needed;
1894 while (n > 1 && b_divisor[n - 1] == 0)
1895 n--;
1896
1897 memset (b_quotient, 0, sizeof (b_quotient));
1898
1899 divmod_internal_2 (b_quotient, b_remainder, b_dividend, b_divisor, m, n);
1900
1901 unsigned int quotient_len = 0;
1902 if (quotient)
1903 {
1904 quotient_len = wi_pack (quotient, b_quotient, m, dividend_prec);
1905 /* The quotient is neg if exactly one of the divisor or dividend is
1906 neg. */
1907 if (dividend_neg != divisor_neg)
1908 quotient_len = wi::sub_large (quotient, zeros, 1, quotient,
1909 quotient_len, dividend_prec,
1910 UNSIGNED, 0);
1911 }
1912
1913 if (remainder)
1914 {
1915 *remainder_len = wi_pack (remainder, b_remainder, n, dividend_prec);
1916 /* The remainder is always the same sign as the dividend. */
1917 if (dividend_neg)
1918 *remainder_len = wi::sub_large (remainder, zeros, 1, remainder,
1919 *remainder_len, dividend_prec,
1920 UNSIGNED, 0);
1921 }
1922
1923 return quotient_len;
1924}
1925
1926/*
1927 * Shifting, rotating and extraction.
1928 */
1929
1930/* Left shift XVAL by SHIFT and store the result in VAL. Return the
1931 number of blocks in VAL. Both XVAL and VAL have PRECISION bits. */
1932unsigned int
1933wi::lshift_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
1934 unsigned int xlen, unsigned int precision,
1935 unsigned int shift)
1936{
1937 /* Split the shift into a whole-block shift and a subblock shift. */
1938 unsigned int skip = shift / HOST_BITS_PER_WIDE_INT64;
1939 unsigned int small_shift = shift % HOST_BITS_PER_WIDE_INT64;
1940
1941 /* The whole-block shift fills with zeros. */
1942 unsigned int len = BLOCKS_NEEDED (precision)(precision ? (((precision) + 64 - 1) / 64) : 1);
1943 for (unsigned int i = 0; i < skip; ++i)
1944 val[i] = 0;
1945
1946 /* It's easier to handle the simple block case specially. */
1947 if (small_shift == 0)
1948 for (unsigned int i = skip; i < len; ++i)
1949 val[i] = safe_uhwi (xval, xlen, i - skip);
1950 else
1951 {
1952 /* The first unfilled output block is a left shift of the first
1953 block in XVAL. The other output blocks contain bits from two
1954 consecutive input blocks. */
1955 unsigned HOST_WIDE_INTlong carry = 0;
1956 for (unsigned int i = skip; i < len; ++i)
1957 {
1958 unsigned HOST_WIDE_INTlong x = safe_uhwi (xval, xlen, i - skip);
1959 val[i] = (x << small_shift) | carry;
1960 carry = x >> (-small_shift % HOST_BITS_PER_WIDE_INT64);
1961 }
1962 }
1963 return canonize (val, len, precision);
1964}
1965
1966/* Right shift XVAL by SHIFT and store the result in VAL. Return the
1967 number of blocks in VAL. The input has XPRECISION bits and the
1968 output has XPRECISION - SHIFT bits. */
1969static unsigned int
1970rshift_large_common (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
1971 unsigned int xlen, unsigned int xprecision,
1972 unsigned int shift)
1973{
1974 /* Split the shift into a whole-block shift and a subblock shift. */
1975 unsigned int skip = shift / HOST_BITS_PER_WIDE_INT64;
1976 unsigned int small_shift = shift % HOST_BITS_PER_WIDE_INT64;
1977
1978 /* Work out how many blocks are needed to store the significant bits
1979 (excluding the upper zeros or signs). */
1980 unsigned int len = BLOCKS_NEEDED (xprecision - shift)(xprecision - shift ? (((xprecision - shift) + 64 - 1) / 64) :
1)
;
1981
1982 /* It's easier to handle the simple block case specially. */
1983 if (small_shift == 0)
1984 for (unsigned int i = 0; i < len; ++i)
1985 val[i] = safe_uhwi (xval, xlen, i + skip);
1986 else
1987 {
1988 /* Each output block but the last is a combination of two input blocks.
1989 The last block is a right shift of the last block in XVAL. */
1990 unsigned HOST_WIDE_INTlong curr = safe_uhwi (xval, xlen, skip);
1991 for (unsigned int i = 0; i < len; ++i)
1992 {
1993 val[i] = curr >> small_shift;
1994 curr = safe_uhwi (xval, xlen, i + skip + 1);
1995 val[i] |= curr << (-small_shift % HOST_BITS_PER_WIDE_INT64);
1996 }
1997 }
1998 return len;
1999}
2000
2001/* Logically right shift XVAL by SHIFT and store the result in VAL.
2002 Return the number of blocks in VAL. XVAL has XPRECISION bits and
2003 VAL has PRECISION bits. */
2004unsigned int
2005wi::lrshift_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
2006 unsigned int xlen, unsigned int xprecision,
2007 unsigned int precision, unsigned int shift)
2008{
2009 unsigned int len = rshift_large_common (val, xval, xlen, xprecision, shift);
2010
2011 /* The value we just created has precision XPRECISION - SHIFT.
2012 Zero-extend it to wider precisions. */
2013 if (precision > xprecision - shift)
2014 {
2015 unsigned int small_prec = (xprecision - shift) % HOST_BITS_PER_WIDE_INT64;
2016 if (small_prec)
2017 val[len - 1] = zext_hwi (val[len - 1], small_prec);
2018 else if (val[len - 1] < 0)
2019 {
2020 /* Add a new block with a zero. */
2021 val[len++] = 0;
2022 return len;
2023 }
2024 }
2025 return canonize (val, len, precision);
2026}
2027
2028/* Arithmetically right shift XVAL by SHIFT and store the result in VAL.
2029 Return the number of blocks in VAL. XVAL has XPRECISION bits and
2030 VAL has PRECISION bits. */
2031unsigned int
2032wi::arshift_large (HOST_WIDE_INTlong *val, const HOST_WIDE_INTlong *xval,
2033 unsigned int xlen, unsigned int xprecision,
2034 unsigned int precision, unsigned int shift)
2035{
2036 unsigned int len = rshift_large_common (val, xval, xlen, xprecision, shift);
2037
2038 /* The value we just created has precision XPRECISION - SHIFT.
2039 Sign-extend it to wider types. */
2040 if (precision > xprecision - shift)
2041 {
2042 unsigned int small_prec = (xprecision - shift) % HOST_BITS_PER_WIDE_INT64;
2043 if (small_prec)
2044 val[len - 1] = sext_hwi (val[len - 1], small_prec);
2045 }
2046 return canonize (val, len, precision);
2047}
2048
2049/* Return the number of leading (upper) zeros in X. */
2050int
2051wi::clz (const wide_int_ref &x)
2052{
2053 if (x.sign_mask () < 0)
2054 /* The upper bit is set, so there are no leading zeros. */
2055 return 0;
2056
2057 /* Calculate how many bits there above the highest represented block. */
2058 int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT64;
2059
2060 unsigned HOST_WIDE_INTlong high = x.uhigh ();
2061 if (count < 0)
2062 /* The upper -COUNT bits of HIGH are not part of the value.
2063 Clear them out. */
2064 high = (high << -count) >> -count;
2065
2066 /* We don't need to look below HIGH. Either HIGH is nonzero,
2067 or the top bit of the block below is nonzero; clz_hwi is
2068 HOST_BITS_PER_WIDE_INT in the latter case. */
2069 return count + clz_hwi (high);
2070}
2071
2072/* Return the number of redundant sign bits in X. (That is, the number
2073 of bits immediately below the sign bit that have the same value as
2074 the sign bit.) */
2075int
2076wi::clrsb (const wide_int_ref &x)
2077{
2078 /* Calculate how many bits there above the highest represented block. */
2079 int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT64;
2080
2081 unsigned HOST_WIDE_INTlong high = x.uhigh ();
2082 unsigned HOST_WIDE_INTlong mask = -1;
2083 if (count < 0)
2084 {
2085 /* The upper -COUNT bits of HIGH are not part of the value.
2086 Clear them from both MASK and HIGH. */
2087 mask >>= -count;
2088 high &= mask;
2089 }
2090
2091 /* If the top bit is 1, count the number of leading 1s. If the top
2092 bit is zero, count the number of leading zeros. */
2093 if (high > mask / 2)
2094 high ^= mask;
2095
2096 /* There are no sign bits below the top block, so we don't need to look
2097 beyond HIGH. Note that clz_hwi is HOST_BITS_PER_WIDE_INT when
2098 HIGH is 0. */
2099 return count + clz_hwi (high) - 1;
2100}
2101
2102/* Return the number of trailing (lower) zeros in X. */
2103int
2104wi::ctz (const wide_int_ref &x)
2105{
2106 if (x.len == 1 && x.ulow () == 0)
2107 return x.precision;
2108
2109 /* Having dealt with the zero case, there must be a block with a
2110 nonzero bit. We don't care about the bits above the first 1. */
2111 unsigned int i = 0;
2112 while (x.val[i] == 0)
2113 ++i;
2114 return i * HOST_BITS_PER_WIDE_INT64 + ctz_hwi (x.val[i]);
2115}
2116
2117/* If X is an exact power of 2, return the base-2 logarithm, otherwise
2118 return -1. */
2119int
2120wi::exact_log2 (const wide_int_ref &x)
2121{
2122 /* Reject cases where there are implicit -1 blocks above HIGH. */
2123 if (x.len * HOST_BITS_PER_WIDE_INT64 < x.precision && x.sign_mask () < 0)
2124 return -1;
2125
2126 /* Set CRUX to the index of the entry that should be nonzero.
2127 If the top block is zero then the next lowest block (if any)
2128 must have the high bit set. */
2129 unsigned int crux = x.len - 1;
2130 if (crux > 0 && x.val[crux] == 0)
2131 crux -= 1;
2132
2133 /* Check that all lower blocks are zero. */
2134 for (unsigned int i = 0; i < crux; ++i)
2135 if (x.val[i] != 0)
2136 return -1;
2137
2138 /* Get a zero-extended form of block CRUX. */
2139 unsigned HOST_WIDE_INTlong hwi = x.val[crux];
2140 if ((crux + 1) * HOST_BITS_PER_WIDE_INT64 > x.precision)
2141 hwi = zext_hwi (hwi, x.precision % HOST_BITS_PER_WIDE_INT64);
2142
2143 /* Now it's down to whether HWI is a power of 2. */
2144 int res = ::exact_log2 (hwi);
2145 if (res >= 0)
2146 res += crux * HOST_BITS_PER_WIDE_INT64;
2147 return res;
2148}
2149
2150/* Return the base-2 logarithm of X, rounding down. Return -1 if X is 0. */
2151int
2152wi::floor_log2 (const wide_int_ref &x)
2153{
2154 return x.precision - 1 - clz (x);
2155}
2156
2157/* Return the index of the first (lowest) set bit in X, counting from 1.
2158 Return 0 if X is 0. */
2159int
2160wi::ffs (const wide_int_ref &x)
2161{
2162 return eq_p (x, 0) ? 0 : ctz (x) + 1;
2163}
2164
2165/* Return true if sign-extending X to have precision PRECISION would give
2166 the minimum signed value at that precision. */
2167bool
2168wi::only_sign_bit_p (const wide_int_ref &x, unsigned int precision)
2169{
2170 return ctz (x) + 1 == int (precision);
2171}
2172
2173/* Return true if X represents the minimum signed value. */
2174bool
2175wi::only_sign_bit_p (const wide_int_ref &x)
2176{
2177 return only_sign_bit_p (x, x.precision);
2178}
2179
2180/* Return VAL if VAL has no bits set outside MASK. Otherwise round VAL
2181 down to the previous value that has no bits set outside MASK.
2182 This rounding wraps for signed values if VAL is negative and
2183 the top bit of MASK is clear.
2184
2185 For example, round_down_for_mask (6, 0xf1) would give 1 and
2186 round_down_for_mask (24, 0xf1) would give 17. */
2187
2188wide_int
2189wi::round_down_for_mask (const wide_int &val, const wide_int &mask)
2190{
2191 /* Get the bits in VAL that are outside the mask. */
2192 wide_int extra_bits = wi::bit_and_not (val, mask);
2193 if (extra_bits == 0)
2194 return val;
2195
2196 /* Get a mask that includes the top bit in EXTRA_BITS and is all 1s
2197 below that bit. */
2198 unsigned int precision = val.get_precision ();
2199 wide_int lower_mask = wi::mask (precision - wi::clz (extra_bits),
2200 false, precision);
2201
2202 /* Clear the bits that aren't in MASK, but ensure that all bits
2203 in MASK below the top cleared bit are set. */
2204 return (val & mask) | (mask & lower_mask);
2205}
2206
2207/* Return VAL if VAL has no bits set outside MASK. Otherwise round VAL
2208 up to the next value that has no bits set outside MASK. The rounding
2209 wraps if there are no suitable values greater than VAL.
2210
2211 For example, round_up_for_mask (6, 0xf1) would give 16 and
2212 round_up_for_mask (24, 0xf1) would give 32. */
2213
2214wide_int
2215wi::round_up_for_mask (const wide_int &val, const wide_int &mask)
2216{
2217 /* Get the bits in VAL that are outside the mask. */
2218 wide_int extra_bits = wi::bit_and_not (val, mask);
2219 if (extra_bits == 0)
2220 return val;
2221
2222 /* Get a mask that is all 1s above the top bit in EXTRA_BITS. */
2223 unsigned int precision = val.get_precision ();
2224 wide_int upper_mask = wi::mask (precision - wi::clz (extra_bits),
2225 true, precision);
2226
2227 /* Get the bits of the mask that are above the top bit in EXTRA_BITS. */
2228 upper_mask &= mask;
2229
2230 /* Conceptually we need to:
2231
2232 - clear bits of VAL outside UPPER_MASK
2233 - add the lowest bit in UPPER_MASK to VAL (or add 0 if UPPER_MASK is 0)
2234 - propagate the carry through the bits of VAL in UPPER_MASK
2235
2236 If (~VAL & UPPER_MASK) is nonzero, the carry eventually
2237 reaches that bit and the process leaves all lower bits clear.
2238 If (~VAL & UPPER_MASK) is zero then the result is also zero. */
2239 wide_int tmp = wi::bit_and_not (upper_mask, val);
2240
2241 return (val | tmp) & -tmp;
2242}
2243
2244/* Compute the modular multiplicative inverse of A modulo B
2245 using extended Euclid's algorithm. Assumes A and B are coprime,
2246 and that A and B have the same precision. */
2247wide_int
2248wi::mod_inv (const wide_int &a, const wide_int &b)
2249{
2250 /* Verify the assumption. */
2251 gcc_checking_assert (wi::eq_p (wi::gcd (a, b), 1))((void)(!(wi::eq_p (wi::gcd (a, b), 1)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2251, __FUNCTION__), 0 : 0))
;
1
Calling 'gcd<generic_wide_int<wide_int_storage>, generic_wide_int<wide_int_storage>>'
2252
2253 unsigned int p = a.get_precision () + 1;
2254 gcc_checking_assert (b.get_precision () + 1 == p)((void)(!(b.get_precision () + 1 == p) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2254, __FUNCTION__), 0 : 0))
;
2255 wide_int c = wide_int::from (a, p, UNSIGNED);
2256 wide_int d = wide_int::from (b, p, UNSIGNED);
2257 wide_int x0 = wide_int::from (0, p, UNSIGNED);
2258 wide_int x1 = wide_int::from (1, p, UNSIGNED);
2259
2260 if (wi::eq_p (b, 1))
2261 return wide_int::from (1, p, UNSIGNED);
2262
2263 while (wi::gt_p (c, 1, UNSIGNED))
2264 {
2265 wide_int t = d;
2266 wide_int q = wi::divmod_trunc (c, d, UNSIGNED, &d);
2267 c = t;
2268 wide_int s = x0;
2269 x0 = wi::sub (x1, wi::mul (q, x0));
2270 x1 = s;
2271 }
2272 if (wi::lt_p (x1, 0, SIGNED))
2273 x1 += d;
2274 return x1;
2275}
2276
2277/*
2278 * Private utilities.
2279 */
2280
2281void gt_ggc_mx (widest_int *) { }
2282void gt_pch_nx (widest_int *, void (*) (void *, void *), void *) { }
2283void gt_pch_nx (widest_int *) { }
2284
2285template void wide_int::dump () const;
2286template void generic_wide_int <wide_int_ref_storage <false> >::dump () const;
2287template void generic_wide_int <wide_int_ref_storage <true> >::dump () const;
2288template void offset_int::dump () const;
2289template void widest_int::dump () const;
2290
2291/* We could add all the above ::dump variants here, but wide_int and
2292 widest_int should handle the common cases. Besides, you can always
2293 call the dump method directly. */
2294
2295DEBUG_FUNCTION__attribute__ ((__used__)) void
2296debug (const wide_int &ref)
2297{
2298 ref.dump ();
2299}
2300
2301DEBUG_FUNCTION__attribute__ ((__used__)) void
2302debug (const wide_int *ptr)
2303{
2304 if (ptr)
2305 debug (*ptr);
2306 else
2307 fprintf (stderrstderr, "<nil>\n");
2308}
2309
2310DEBUG_FUNCTION__attribute__ ((__used__)) void
2311debug (const widest_int &ref)
2312{
2313 ref.dump ();
2314}
2315
2316DEBUG_FUNCTION__attribute__ ((__used__)) void
2317debug (const widest_int *ptr)
2318{
2319 if (ptr)
2320 debug (*ptr);
2321 else
2322 fprintf (stderrstderr, "<nil>\n");
2323}
2324
2325#if CHECKING_P1
2326
2327namespace selftest {
2328
2329/* Selftests for wide ints. We run these multiple times, once per type. */
2330
2331/* Helper function for building a test value. */
2332
2333template <class VALUE_TYPE>
2334static VALUE_TYPE
2335from_int (int i);
2336
2337/* Specializations of the fixture for each wide-int type. */
2338
2339/* Specialization for VALUE_TYPE == wide_int. */
2340
2341template <>
2342wide_int
2343from_int (int i)
2344{
2345 return wi::shwi (i, 32);
2346}
2347
2348/* Specialization for VALUE_TYPE == offset_int. */
2349
2350template <>
2351offset_int
2352from_int (int i)
2353{
2354 return offset_int (i);
2355}
2356
2357/* Specialization for VALUE_TYPE == widest_int. */
2358
2359template <>
2360widest_int
2361from_int (int i)
2362{
2363 return widest_int (i);
2364}
2365
2366/* Verify that print_dec (WI, ..., SGN) gives the expected string
2367 representation (using base 10). */
2368
2369static void
2370assert_deceq (const char *expected, const wide_int_ref &wi, signop sgn)
2371{
2372 char buf[WIDE_INT_PRINT_BUFFER_SIZE(((((64*(8)) + 64) / 64) * 64) / 4 + 4)];
2373 print_dec (wi, buf, sgn);
2374 ASSERT_STREQ (expected, buf)do { ::selftest::assert_streq ((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2374, __FUNCTION__)), "expected", "buf", (expected), (buf))
; } while (0)
;
2375}
2376
2377/* Likewise for base 16. */
2378
2379static void
2380assert_hexeq (const char *expected, const wide_int_ref &wi)
2381{
2382 char buf[WIDE_INT_PRINT_BUFFER_SIZE(((((64*(8)) + 64) / 64) * 64) / 4 + 4)];
2383 print_hex (wi, buf);
2384 ASSERT_STREQ (expected, buf)do { ::selftest::assert_streq ((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2384, __FUNCTION__)), "expected", "buf", (expected), (buf))
; } while (0)
;
2385}
2386
2387/* Test cases. */
2388
2389/* Verify that print_dec and print_hex work for VALUE_TYPE. */
2390
2391template <class VALUE_TYPE>
2392static void
2393test_printing ()
2394{
2395 VALUE_TYPE a = from_int<VALUE_TYPE> (42);
2396 assert_deceq ("42", a, SIGNED);
2397 assert_hexeq ("0x2a", a);
2398 assert_hexeq ("0x1fffffffffffffffff", wi::shwi (-1, 69));
2399 assert_hexeq ("0xffffffffffffffff", wi::mask (64, false, 69));
2400 assert_hexeq ("0xffffffffffffffff", wi::mask <widest_int> (64, false));
2401 if (WIDE_INT_MAX_PRECISION((((64*(8)) + 64) / 64) * 64) > 128)
2402 {
2403 assert_hexeq ("0x20000000000000000fffffffffffffffe",
2404 wi::lshift (1, 129) + wi::lshift (1, 64) - 2);
2405 assert_hexeq ("0x200000000000004000123456789abcdef",
2406 wi::lshift (1, 129) + wi::lshift (1, 74)
2407 + wi::lshift (0x1234567, 32) + 0x89abcdef);
2408 }
2409}
2410
2411/* Verify that various operations work correctly for VALUE_TYPE,
2412 unary and binary, using both function syntax, and
2413 overloaded-operators. */
2414
2415template <class VALUE_TYPE>
2416static void
2417test_ops ()
2418{
2419 VALUE_TYPE a = from_int<VALUE_TYPE> (7);
2420 VALUE_TYPE b = from_int<VALUE_TYPE> (3);
2421
2422 /* Using functions. */
2423 assert_deceq ("-7", wi::neg (a), SIGNED);
2424 assert_deceq ("10", wi::add (a, b), SIGNED);
2425 assert_deceq ("4", wi::sub (a, b), SIGNED);
2426 assert_deceq ("-4", wi::sub (b, a), SIGNED);
2427 assert_deceq ("21", wi::mul (a, b), SIGNED);
2428
2429 /* Using operators. */
2430 assert_deceq ("-7", -a, SIGNED);
2431 assert_deceq ("10", a + b, SIGNED);
2432 assert_deceq ("4", a - b, SIGNED);
2433 assert_deceq ("-4", b - a, SIGNED);
2434 assert_deceq ("21", a * b, SIGNED);
2435}
2436
2437/* Verify that various comparisons work correctly for VALUE_TYPE. */
2438
2439template <class VALUE_TYPE>
2440static void
2441test_comparisons ()
2442{
2443 VALUE_TYPE a = from_int<VALUE_TYPE> (7);
2444 VALUE_TYPE b = from_int<VALUE_TYPE> (3);
2445
2446 /* == */
2447 ASSERT_TRUE (wi::eq_p (a, a))do { const char *desc_ = "ASSERT_TRUE (" "(wi::eq_p (a, a))" ")"
; bool actual_ = ((wi::eq_p (a, a))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2447, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2447, __FUNCTION__))), desc_); } while (0)
;
2448 ASSERT_FALSE (wi::eq_p (a, b))do { const char *desc_ = "ASSERT_FALSE (" "(wi::eq_p (a, b))"
")"; bool actual_ = ((wi::eq_p (a, b))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2448, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2448, __FUNCTION__))), desc_); } while (0)
;
2449
2450 /* != */
2451 ASSERT_TRUE (wi::ne_p (a, b))do { const char *desc_ = "ASSERT_TRUE (" "(wi::ne_p (a, b))" ")"
; bool actual_ = ((wi::ne_p (a, b))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2451, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2451, __FUNCTION__))), desc_); } while (0)
;
2452 ASSERT_FALSE (wi::ne_p (a, a))do { const char *desc_ = "ASSERT_FALSE (" "(wi::ne_p (a, a))"
")"; bool actual_ = ((wi::ne_p (a, a))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2452, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2452, __FUNCTION__))), desc_); } while (0)
;
2453
2454 /* < */
2455 ASSERT_FALSE (wi::lts_p (a, a))do { const char *desc_ = "ASSERT_FALSE (" "(wi::lts_p (a, a))"
")"; bool actual_ = ((wi::lts_p (a, a))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2455, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2455, __FUNCTION__))), desc_); } while (0)
;
2456 ASSERT_FALSE (wi::lts_p (a, b))do { const char *desc_ = "ASSERT_FALSE (" "(wi::lts_p (a, b))"
")"; bool actual_ = ((wi::lts_p (a, b))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2456, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2456, __FUNCTION__))), desc_); } while (0)
;
2457 ASSERT_TRUE (wi::lts_p (b, a))do { const char *desc_ = "ASSERT_TRUE (" "(wi::lts_p (b, a))"
")"; bool actual_ = ((wi::lts_p (b, a))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2457, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2457, __FUNCTION__))), desc_); } while (0)
;
2458
2459 /* <= */
2460 ASSERT_TRUE (wi::les_p (a, a))do { const char *desc_ = "ASSERT_TRUE (" "(wi::les_p (a, a))"
")"; bool actual_ = ((wi::les_p (a, a))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2460, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2460, __FUNCTION__))), desc_); } while (0)
;
2461 ASSERT_FALSE (wi::les_p (a, b))do { const char *desc_ = "ASSERT_FALSE (" "(wi::les_p (a, b))"
")"; bool actual_ = ((wi::les_p (a, b))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2461, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2461, __FUNCTION__))), desc_); } while (0)
;
2462 ASSERT_TRUE (wi::les_p (b, a))do { const char *desc_ = "ASSERT_TRUE (" "(wi::les_p (b, a))"
")"; bool actual_ = ((wi::les_p (b, a))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2462, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2462, __FUNCTION__))), desc_); } while (0)
;
2463
2464 /* > */
2465 ASSERT_FALSE (wi::gts_p (a, a))do { const char *desc_ = "ASSERT_FALSE (" "(wi::gts_p (a, a))"
")"; bool actual_ = ((wi::gts_p (a, a))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2465, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2465, __FUNCTION__))), desc_); } while (0)
;
2466 ASSERT_TRUE (wi::gts_p (a, b))do { const char *desc_ = "ASSERT_TRUE (" "(wi::gts_p (a, b))"
")"; bool actual_ = ((wi::gts_p (a, b))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2466, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2466, __FUNCTION__))), desc_); } while (0)
;
2467 ASSERT_FALSE (wi::gts_p (b, a))do { const char *desc_ = "ASSERT_FALSE (" "(wi::gts_p (b, a))"
")"; bool actual_ = ((wi::gts_p (b, a))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2467, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2467, __FUNCTION__))), desc_); } while (0)
;
2468
2469 /* >= */
2470 ASSERT_TRUE (wi::ges_p (a, a))do { const char *desc_ = "ASSERT_TRUE (" "(wi::ges_p (a, a))"
")"; bool actual_ = ((wi::ges_p (a, a))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2470, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2470, __FUNCTION__))), desc_); } while (0)
;
2471 ASSERT_TRUE (wi::ges_p (a, b))do { const char *desc_ = "ASSERT_TRUE (" "(wi::ges_p (a, b))"
")"; bool actual_ = ((wi::ges_p (a, b))); if (actual_) ::selftest
::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2471, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2471, __FUNCTION__))), desc_); } while (0)
;
2472 ASSERT_FALSE (wi::ges_p (b, a))do { const char *desc_ = "ASSERT_FALSE (" "(wi::ges_p (b, a))"
")"; bool actual_ = ((wi::ges_p (b, a))); if (actual_) ::selftest
::fail (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2472, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2472, __FUNCTION__))), desc_); } while (0)
;
2473
2474 /* comparison */
2475 ASSERT_EQ (-1, wi::cmps (b, a))do { const char *desc_ = "ASSERT_EQ (" "(-1)" ", " "(wi::cmps (b, a))"
")"; if (((-1)) == ((wi::cmps (b, a)))) ::selftest::pass (((
(::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2475, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2475, __FUNCTION__)))), desc_); } while (0)
;
2476 ASSERT_EQ (0, wi::cmps (a, a))do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(wi::cmps (a, a))"
")"; if (((0)) == ((wi::cmps (a, a)))) ::selftest::pass ((((
::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2476, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2476, __FUNCTION__)))), desc_); } while (0)
;
2477 ASSERT_EQ (1, wi::cmps (a, b))do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(wi::cmps (a, b))"
")"; if (((1)) == ((wi::cmps (a, b)))) ::selftest::pass ((((
::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2477, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2477, __FUNCTION__)))), desc_); } while (0)
;
2478}
2479
2480/* Run all of the selftests, using the given VALUE_TYPE. */
2481
2482template <class VALUE_TYPE>
2483static void run_all_wide_int_tests ()
2484{
2485 test_printing <VALUE_TYPE> ();
2486 test_ops <VALUE_TYPE> ();
2487 test_comparisons <VALUE_TYPE> ();
2488}
2489
2490/* Test overflow conditions. */
2491
2492static void
2493test_overflow ()
2494{
2495 static int precs[] = { 31, 32, 33, 63, 64, 65, 127, 128 };
2496 static int offsets[] = { 16, 1, 0 };
2497 for (unsigned int i = 0; i < ARRAY_SIZE (precs)(sizeof (precs) / sizeof ((precs)[0])); ++i)
2498 for (unsigned int j = 0; j < ARRAY_SIZE (offsets)(sizeof (offsets) / sizeof ((offsets)[0])); ++j)
2499 {
2500 int prec = precs[i];
2501 int offset = offsets[j];
2502 wi::overflow_type overflow;
2503 wide_int sum, diff;
2504
2505 sum = wi::add (wi::max_value (prec, UNSIGNED) - offset, 1,
2506 UNSIGNED, &overflow);
2507 ASSERT_EQ (sum, -offset)do { const char *desc_ = "ASSERT_EQ (" "(sum)" ", " "(-offset)"
")"; if (((sum)) == ((-offset))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2507, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2507, __FUNCTION__)))), desc_); } while (0)
;
2508 ASSERT_EQ (overflow != wi::OVF_NONE, offset == 0)do { const char *desc_ = "ASSERT_EQ (" "(overflow != wi::OVF_NONE)"
", " "(offset == 0)" ")"; if (((overflow != wi::OVF_NONE)) ==
((offset == 0))) ::selftest::pass ((((::selftest::location (
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2508, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2508, __FUNCTION__)))), desc_); } while (0)
;
2509
2510 sum = wi::add (1, wi::max_value (prec, UNSIGNED) - offset,
2511 UNSIGNED, &overflow);
2512 ASSERT_EQ (sum, -offset)do { const char *desc_ = "ASSERT_EQ (" "(sum)" ", " "(-offset)"
")"; if (((sum)) == ((-offset))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2512, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2512, __FUNCTION__)))), desc_); } while (0)
;
2513 ASSERT_EQ (overflow != wi::OVF_NONE, offset == 0)do { const char *desc_ = "ASSERT_EQ (" "(overflow != wi::OVF_NONE)"
", " "(offset == 0)" ")"; if (((overflow != wi::OVF_NONE)) ==
((offset == 0))) ::selftest::pass ((((::selftest::location (
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2513, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2513, __FUNCTION__)))), desc_); } while (0)
;
2514
2515 diff = wi::sub (wi::max_value (prec, UNSIGNED) - offset,
2516 wi::max_value (prec, UNSIGNED),
2517 UNSIGNED, &overflow);
2518 ASSERT_EQ (diff, -offset)do { const char *desc_ = "ASSERT_EQ (" "(diff)" ", " "(-offset)"
")"; if (((diff)) == ((-offset))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2518, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2518, __FUNCTION__)))), desc_); } while (0)
;
2519 ASSERT_EQ (overflow != wi::OVF_NONE, offset != 0)do { const char *desc_ = "ASSERT_EQ (" "(overflow != wi::OVF_NONE)"
", " "(offset != 0)" ")"; if (((overflow != wi::OVF_NONE)) ==
((offset != 0))) ::selftest::pass ((((::selftest::location (
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2519, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2519, __FUNCTION__)))), desc_); } while (0)
;
2520
2521 diff = wi::sub (wi::max_value (prec, UNSIGNED) - offset,
2522 wi::max_value (prec, UNSIGNED) - 1,
2523 UNSIGNED, &overflow);
2524 ASSERT_EQ (diff, 1 - offset)do { const char *desc_ = "ASSERT_EQ (" "(diff)" ", " "(1 - offset)"
")"; if (((diff)) == ((1 - offset))) ::selftest::pass ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2524, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2524, __FUNCTION__)))), desc_); } while (0)
;
2525 ASSERT_EQ (overflow != wi::OVF_NONE, offset > 1)do { const char *desc_ = "ASSERT_EQ (" "(overflow != wi::OVF_NONE)"
", " "(offset > 1)" ")"; if (((overflow != wi::OVF_NONE))
== ((offset > 1))) ::selftest::pass ((((::selftest::location
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2525, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2525, __FUNCTION__)))), desc_); } while (0)
;
2526 }
2527}
2528
2529/* Test the round_{down,up}_for_mask functions. */
2530
2531static void
2532test_round_for_mask ()
2533{
2534 unsigned int prec = 18;
2535 ASSERT_EQ (17, wi::round_down_for_mask (wi::shwi (17, prec),do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_down_for_mask (wi::shwi (17, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_down_for_mask (wi::shwi (17, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2536, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2536, __FUNCTION__)))), desc_); } while (0)
2536 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_down_for_mask (wi::shwi (17, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_down_for_mask (wi::shwi (17, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2536, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2536, __FUNCTION__)))), desc_); } while (0)
;
2537 ASSERT_EQ (17, wi::round_up_for_mask (wi::shwi (17, prec),do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_up_for_mask (wi::shwi (17, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_up_for_mask (wi::shwi (17, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2538, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2538, __FUNCTION__)))), desc_); } while (0)
2538 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_up_for_mask (wi::shwi (17, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_up_for_mask (wi::shwi (17, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2538, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2538, __FUNCTION__)))), desc_); } while (0)
;
2539
2540 ASSERT_EQ (1, wi::round_down_for_mask (wi::shwi (6, prec),do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(wi::round_down_for_mask (wi::shwi (6, prec), wi::shwi (0xf1, prec)))"
")"; if (((1)) == ((wi::round_down_for_mask (wi::shwi (6, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2541, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2541, __FUNCTION__)))), desc_); } while (0)
2541 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(1)" ", " "(wi::round_down_for_mask (wi::shwi (6, prec), wi::shwi (0xf1, prec)))"
")"; if (((1)) == ((wi::round_down_for_mask (wi::shwi (6, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2541, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2541, __FUNCTION__)))), desc_); } while (0)
;
2542 ASSERT_EQ (16, wi::round_up_for_mask (wi::shwi (6, prec),do { const char *desc_ = "ASSERT_EQ (" "(16)" ", " "(wi::round_up_for_mask (wi::shwi (6, prec), wi::shwi (0xf1, prec)))"
")"; if (((16)) == ((wi::round_up_for_mask (wi::shwi (6, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2543, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2543, __FUNCTION__)))), desc_); } while (0)
2543 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(16)" ", " "(wi::round_up_for_mask (wi::shwi (6, prec), wi::shwi (0xf1, prec)))"
")"; if (((16)) == ((wi::round_up_for_mask (wi::shwi (6, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2543, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2543, __FUNCTION__)))), desc_); } while (0)
;
2544
2545 ASSERT_EQ (17, wi::round_down_for_mask (wi::shwi (24, prec),do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_down_for_mask (wi::shwi (24, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_down_for_mask (wi::shwi (24, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2546, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2546, __FUNCTION__)))), desc_); } while (0)
2546 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(17)" ", " "(wi::round_down_for_mask (wi::shwi (24, prec), wi::shwi (0xf1, prec)))"
")"; if (((17)) == ((wi::round_down_for_mask (wi::shwi (24, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2546, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2546, __FUNCTION__)))), desc_); } while (0)
;
2547 ASSERT_EQ (32, wi::round_up_for_mask (wi::shwi (24, prec),do { const char *desc_ = "ASSERT_EQ (" "(32)" ", " "(wi::round_up_for_mask (wi::shwi (24, prec), wi::shwi (0xf1, prec)))"
")"; if (((32)) == ((wi::round_up_for_mask (wi::shwi (24, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2548, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2548, __FUNCTION__)))), desc_); } while (0)
2548 wi::shwi (0xf1, prec)))do { const char *desc_ = "ASSERT_EQ (" "(32)" ", " "(wi::round_up_for_mask (wi::shwi (24, prec), wi::shwi (0xf1, prec)))"
")"; if (((32)) == ((wi::round_up_for_mask (wi::shwi (24, prec
), wi::shwi (0xf1, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2548, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2548, __FUNCTION__)))), desc_); } while (0)
;
2549
2550 ASSERT_EQ (0x011, wi::round_down_for_mask (wi::shwi (0x22, prec),do { const char *desc_ = "ASSERT_EQ (" "(0x011)" ", " "(wi::round_down_for_mask (wi::shwi (0x22, prec), wi::shwi (0x111, prec)))"
")"; if (((0x011)) == ((wi::round_down_for_mask (wi::shwi (0x22
, prec), wi::shwi (0x111, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2551, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2551, __FUNCTION__)))), desc_); } while (0)
2551 wi::shwi (0x111, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0x011)" ", " "(wi::round_down_for_mask (wi::shwi (0x22, prec), wi::shwi (0x111, prec)))"
")"; if (((0x011)) == ((wi::round_down_for_mask (wi::shwi (0x22
, prec), wi::shwi (0x111, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2551, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2551, __FUNCTION__)))), desc_); } while (0)
;
2552 ASSERT_EQ (0x100, wi::round_up_for_mask (wi::shwi (0x22, prec),do { const char *desc_ = "ASSERT_EQ (" "(0x100)" ", " "(wi::round_up_for_mask (wi::shwi (0x22, prec), wi::shwi (0x111, prec)))"
")"; if (((0x100)) == ((wi::round_up_for_mask (wi::shwi (0x22
, prec), wi::shwi (0x111, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2553, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2553, __FUNCTION__)))), desc_); } while (0)
2553 wi::shwi (0x111, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0x100)" ", " "(wi::round_up_for_mask (wi::shwi (0x22, prec), wi::shwi (0x111, prec)))"
")"; if (((0x100)) == ((wi::round_up_for_mask (wi::shwi (0x22
, prec), wi::shwi (0x111, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2553, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2553, __FUNCTION__)))), desc_); } while (0)
;
2554
2555 ASSERT_EQ (100, wi::round_down_for_mask (wi::shwi (101, prec),do { const char *desc_ = "ASSERT_EQ (" "(100)" ", " "(wi::round_down_for_mask (wi::shwi (101, prec), wi::shwi (0xfc, prec)))"
")"; if (((100)) == ((wi::round_down_for_mask (wi::shwi (101
, prec), wi::shwi (0xfc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2556, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2556, __FUNCTION__)))), desc_); } while (0)
2556 wi::shwi (0xfc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(100)" ", " "(wi::round_down_for_mask (wi::shwi (101, prec), wi::shwi (0xfc, prec)))"
")"; if (((100)) == ((wi::round_down_for_mask (wi::shwi (101
, prec), wi::shwi (0xfc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2556, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2556, __FUNCTION__)))), desc_); } while (0)
;
2557 ASSERT_EQ (104, wi::round_up_for_mask (wi::shwi (101, prec),do { const char *desc_ = "ASSERT_EQ (" "(104)" ", " "(wi::round_up_for_mask (wi::shwi (101, prec), wi::shwi (0xfc, prec)))"
")"; if (((104)) == ((wi::round_up_for_mask (wi::shwi (101, prec
), wi::shwi (0xfc, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2558, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2558, __FUNCTION__)))), desc_); } while (0)
2558 wi::shwi (0xfc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(104)" ", " "(wi::round_up_for_mask (wi::shwi (101, prec), wi::shwi (0xfc, prec)))"
")"; if (((104)) == ((wi::round_up_for_mask (wi::shwi (101, prec
), wi::shwi (0xfc, prec))))) ::selftest::pass ((((::selftest::
location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2558, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2558, __FUNCTION__)))), desc_); } while (0)
;
2559
2560 ASSERT_EQ (0x2bc, wi::round_down_for_mask (wi::shwi (0x2c2, prec),do { const char *desc_ = "ASSERT_EQ (" "(0x2bc)" ", " "(wi::round_down_for_mask (wi::shwi (0x2c2, prec), wi::shwi (0xabc, prec)))"
")"; if (((0x2bc)) == ((wi::round_down_for_mask (wi::shwi (0x2c2
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2561, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2561, __FUNCTION__)))), desc_); } while (0)
2561 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0x2bc)" ", " "(wi::round_down_for_mask (wi::shwi (0x2c2, prec), wi::shwi (0xabc, prec)))"
")"; if (((0x2bc)) == ((wi::round_down_for_mask (wi::shwi (0x2c2
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2561, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2561, __FUNCTION__)))), desc_); } while (0)
;
2562 ASSERT_EQ (0x800, wi::round_up_for_mask (wi::shwi (0x2c2, prec),do { const char *desc_ = "ASSERT_EQ (" "(0x800)" ", " "(wi::round_up_for_mask (wi::shwi (0x2c2, prec), wi::shwi (0xabc, prec)))"
")"; if (((0x800)) == ((wi::round_up_for_mask (wi::shwi (0x2c2
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2563, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2563, __FUNCTION__)))), desc_); } while (0)
2563 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0x800)" ", " "(wi::round_up_for_mask (wi::shwi (0x2c2, prec), wi::shwi (0xabc, prec)))"
")"; if (((0x800)) == ((wi::round_up_for_mask (wi::shwi (0x2c2
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2563, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2563, __FUNCTION__)))), desc_); } while (0)
;
2564
2565 ASSERT_EQ (0xabc, wi::round_down_for_mask (wi::shwi (0xabd, prec),do { const char *desc_ = "ASSERT_EQ (" "(0xabc)" ", " "(wi::round_down_for_mask (wi::shwi (0xabd, prec), wi::shwi (0xabc, prec)))"
")"; if (((0xabc)) == ((wi::round_down_for_mask (wi::shwi (0xabd
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2566, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2566, __FUNCTION__)))), desc_); } while (0)
2566 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0xabc)" ", " "(wi::round_down_for_mask (wi::shwi (0xabd, prec), wi::shwi (0xabc, prec)))"
")"; if (((0xabc)) == ((wi::round_down_for_mask (wi::shwi (0xabd
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2566, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2566, __FUNCTION__)))), desc_); } while (0)
;
2567 ASSERT_EQ (0, wi::round_up_for_mask (wi::shwi (0xabd, prec),do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(wi::round_up_for_mask (wi::shwi (0xabd, prec), wi::shwi (0xabc, prec)))"
")"; if (((0)) == ((wi::round_up_for_mask (wi::shwi (0xabd, prec
), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2568, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2568, __FUNCTION__)))), desc_); } while (0)
2568 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(wi::round_up_for_mask (wi::shwi (0xabd, prec), wi::shwi (0xabc, prec)))"
")"; if (((0)) == ((wi::round_up_for_mask (wi::shwi (0xabd, prec
), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2568, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2568, __FUNCTION__)))), desc_); } while (0)
;
2569
2570 ASSERT_EQ (0xabc, wi::round_down_for_mask (wi::shwi (0x1000, prec),do { const char *desc_ = "ASSERT_EQ (" "(0xabc)" ", " "(wi::round_down_for_mask (wi::shwi (0x1000, prec), wi::shwi (0xabc, prec)))"
")"; if (((0xabc)) == ((wi::round_down_for_mask (wi::shwi (0x1000
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2571, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2571, __FUNCTION__)))), desc_); } while (0)
2571 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0xabc)" ", " "(wi::round_down_for_mask (wi::shwi (0x1000, prec), wi::shwi (0xabc, prec)))"
")"; if (((0xabc)) == ((wi::round_down_for_mask (wi::shwi (0x1000
, prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2571, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2571, __FUNCTION__)))), desc_); } while (0)
;
2572 ASSERT_EQ (0, wi::round_up_for_mask (wi::shwi (0x1000, prec),do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(wi::round_up_for_mask (wi::shwi (0x1000, prec), wi::shwi (0xabc, prec)))"
")"; if (((0)) == ((wi::round_up_for_mask (wi::shwi (0x1000,
prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2573, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2573, __FUNCTION__)))), desc_); } while (0)
2573 wi::shwi (0xabc, prec)))do { const char *desc_ = "ASSERT_EQ (" "(0)" ", " "(wi::round_up_for_mask (wi::shwi (0x1000, prec), wi::shwi (0xabc, prec)))"
")"; if (((0)) == ((wi::round_up_for_mask (wi::shwi (0x1000,
prec), wi::shwi (0xabc, prec))))) ::selftest::pass ((((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2573, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.cc"
, 2573, __FUNCTION__)))), desc_); } while (0)
;
2574}
2575
2576/* Run all of the selftests within this file, for all value types. */
2577
2578void
2579wide_int_cc_tests ()
2580{
2581 run_all_wide_int_tests <wide_int> ();
2582 run_all_wide_int_tests <offset_int> ();
2583 run_all_wide_int_tests <widest_int> ();
2584 test_overflow ();
2585 test_round_for_mask ();
2586}
2587
2588} // namespace selftest
2589#endif /* CHECKING_P */

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h

1/* Operations with very long integers. -*- C++ -*-
2 Copyright (C) 2012-2021 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 3, or (at your option) any
9later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#ifndef WIDE_INT_H
21#define WIDE_INT_H
22
23/* wide-int.[cc|h] implements a class that efficiently performs
24 mathematical operations on finite precision integers. wide_ints
25 are designed to be transient - they are not for long term storage
26 of values. There is tight integration between wide_ints and the
27 other longer storage GCC representations (rtl and tree).
28
29 The actual precision of a wide_int depends on the flavor. There
30 are three predefined flavors:
31
32 1) wide_int (the default). This flavor does the math in the
33 precision of its input arguments. It is assumed (and checked)
34 that the precisions of the operands and results are consistent.
35 This is the most efficient flavor. It is not possible to examine
36 bits above the precision that has been specified. Because of
37 this, the default flavor has semantics that are simple to
38 understand and in general model the underlying hardware that the
39 compiler is targetted for.
40
41 This flavor must be used at the RTL level of gcc because there
42 is, in general, not enough information in the RTL representation
43 to extend a value beyond the precision specified in the mode.
44
45 This flavor should also be used at the TREE and GIMPLE levels of
46 the compiler except for the circumstances described in the
47 descriptions of the other two flavors.
48
49 The default wide_int representation does not contain any
50 information inherent about signedness of the represented value,
51 so it can be used to represent both signed and unsigned numbers.
52 For operations where the results depend on signedness (full width
53 multiply, division, shifts, comparisons, and operations that need
54 overflow detected), the signedness must be specified separately.
55
56 2) offset_int. This is a fixed-precision integer that can hold
57 any address offset, measured in either bits or bytes, with at
58 least one extra sign bit. At the moment the maximum address
59 size GCC supports is 64 bits. With 8-bit bytes and an extra
60 sign bit, offset_int therefore needs to have at least 68 bits
61 of precision. We round this up to 128 bits for efficiency.
62 Values of type T are converted to this precision by sign- or
63 zero-extending them based on the signedness of T.
64
65 The extra sign bit means that offset_int is effectively a signed
66 128-bit integer, i.e. it behaves like int128_t.
67
68 Since the values are logically signed, there is no need to
69 distinguish between signed and unsigned operations. Sign-sensitive
70 comparison operators <, <=, > and >= are therefore supported.
71 Shift operators << and >> are also supported, with >> being
72 an _arithmetic_ right shift.
73
74 [ Note that, even though offset_int is effectively int128_t,
75 it can still be useful to use unsigned comparisons like
76 wi::leu_p (a, b) as a more efficient short-hand for
77 "a >= 0 && a <= b". ]
78
79 3) widest_int. This representation is an approximation of
80 infinite precision math. However, it is not really infinite
81 precision math as in the GMP library. It is really finite
82 precision math where the precision is 4 times the size of the
83 largest integer that the target port can represent.
84
85 Like offset_int, widest_int is wider than all the values that
86 it needs to represent, so the integers are logically signed.
87 Sign-sensitive comparison operators <, <=, > and >= are supported,
88 as are << and >>.
89
90 There are several places in the GCC where this should/must be used:
91
92 * Code that does induction variable optimizations. This code
93 works with induction variables of many different types at the
94 same time. Because of this, it ends up doing many different
95 calculations where the operands are not compatible types. The
96 widest_int makes this easy, because it provides a field where
97 nothing is lost when converting from any variable,
98
99 * There are a small number of passes that currently use the
100 widest_int that should use the default. These should be
101 changed.
102
103 There are surprising features of offset_int and widest_int
104 that the users should be careful about:
105
106 1) Shifts and rotations are just weird. You have to specify a
107 precision in which the shift or rotate is to happen in. The bits
108 above this precision are zeroed. While this is what you
109 want, it is clearly non obvious.
110
111 2) Larger precision math sometimes does not produce the same
112 answer as would be expected for doing the math at the proper
113 precision. In particular, a multiply followed by a divide will
114 produce a different answer if the first product is larger than
115 what can be represented in the input precision.
116
117 The offset_int and the widest_int flavors are more expensive
118 than the default wide int, so in addition to the caveats with these
119 two, the default is the prefered representation.
120
121 All three flavors of wide_int are represented as a vector of
122 HOST_WIDE_INTs. The default and widest_int vectors contain enough elements
123 to hold a value of MAX_BITSIZE_MODE_ANY_INT bits. offset_int contains only
124 enough elements to hold ADDR_MAX_PRECISION bits. The values are stored
125 in the vector with the least significant HOST_BITS_PER_WIDE_INT bits
126 in element 0.
127
128 The default wide_int contains three fields: the vector (VAL),
129 the precision and a length (LEN). The length is the number of HWIs
130 needed to represent the value. widest_int and offset_int have a
131 constant precision that cannot be changed, so they only store the
132 VAL and LEN fields.
133
134 Since most integers used in a compiler are small values, it is
135 generally profitable to use a representation of the value that is
136 as small as possible. LEN is used to indicate the number of
137 elements of the vector that are in use. The numbers are stored as
138 sign extended numbers as a means of compression. Leading
139 HOST_WIDE_INTs that contain strings of either -1 or 0 are removed
140 as long as they can be reconstructed from the top bit that is being
141 represented.
142
143 The precision and length of a wide_int are always greater than 0.
144 Any bits in a wide_int above the precision are sign-extended from the
145 most significant bit. For example, a 4-bit value 0x8 is represented as
146 VAL = { 0xf...fff8 }. However, as an optimization, we allow other integer
147 constants to be represented with undefined bits above the precision.
148 This allows INTEGER_CSTs to be pre-extended according to TYPE_SIGN,
149 so that the INTEGER_CST representation can be used both in TYPE_PRECISION
150 and in wider precisions.
151
152 There are constructors to create the various forms of wide_int from
153 trees, rtl and constants. For trees the options are:
154
155 tree t = ...;
156 wi::to_wide (t) // Treat T as a wide_int
157 wi::to_offset (t) // Treat T as an offset_int
158 wi::to_widest (t) // Treat T as a widest_int
159
160 All three are light-weight accessors that should have no overhead
161 in release builds. If it is useful for readability reasons to
162 store the result in a temporary variable, the preferred method is:
163
164 wi::tree_to_wide_ref twide = wi::to_wide (t);
165 wi::tree_to_offset_ref toffset = wi::to_offset (t);
166 wi::tree_to_widest_ref twidest = wi::to_widest (t);
167
168 To make an rtx into a wide_int, you have to pair it with a mode.
169 The canonical way to do this is with rtx_mode_t as in:
170
171 rtx r = ...
172 wide_int x = rtx_mode_t (r, mode);
173
174 Similarly, a wide_int can only be constructed from a host value if
175 the target precision is given explicitly, such as in:
176
177 wide_int x = wi::shwi (c, prec); // sign-extend C if necessary
178 wide_int y = wi::uhwi (c, prec); // zero-extend C if necessary
179
180 However, offset_int and widest_int have an inherent precision and so
181 can be initialized directly from a host value:
182
183 offset_int x = (int) c; // sign-extend C
184 widest_int x = (unsigned int) c; // zero-extend C
185
186 It is also possible to do arithmetic directly on rtx_mode_ts and
187 constants. For example:
188
189 wi::add (r1, r2); // add equal-sized rtx_mode_ts r1 and r2
190 wi::add (r1, 1); // add 1 to rtx_mode_t r1
191 wi::lshift (1, 100); // 1 << 100 as a widest_int
192
193 Many binary operations place restrictions on the combinations of inputs,
194 using the following rules:
195
196 - {rtx, wide_int} op {rtx, wide_int} -> wide_int
197 The inputs must be the same precision. The result is a wide_int
198 of the same precision
199
200 - {rtx, wide_int} op (un)signed HOST_WIDE_INT -> wide_int
201 (un)signed HOST_WIDE_INT op {rtx, wide_int} -> wide_int
202 The HOST_WIDE_INT is extended or truncated to the precision of
203 the other input. The result is a wide_int of the same precision
204 as that input.
205
206 - (un)signed HOST_WIDE_INT op (un)signed HOST_WIDE_INT -> widest_int
207 The inputs are extended to widest_int precision and produce a
208 widest_int result.
209
210 - offset_int op offset_int -> offset_int
211 offset_int op (un)signed HOST_WIDE_INT -> offset_int
212 (un)signed HOST_WIDE_INT op offset_int -> offset_int
213
214 - widest_int op widest_int -> widest_int
215 widest_int op (un)signed HOST_WIDE_INT -> widest_int
216 (un)signed HOST_WIDE_INT op widest_int -> widest_int
217
218 Other combinations like:
219
220 - widest_int op offset_int and
221 - wide_int op offset_int
222
223 are not allowed. The inputs should instead be extended or truncated
224 so that they match.
225
226 The inputs to comparison functions like wi::eq_p and wi::lts_p
227 follow the same compatibility rules, although their return types
228 are different. Unary functions on X produce the same result as
229 a binary operation X + X. Shift functions X op Y also produce
230 the same result as X + X; the precision of the shift amount Y
231 can be arbitrarily different from X. */
232
233/* The MAX_BITSIZE_MODE_ANY_INT is automatically generated by a very
234 early examination of the target's mode file. The WIDE_INT_MAX_ELTS
235 can accomodate at least 1 more bit so that unsigned numbers of that
236 mode can be represented as a signed value. Note that it is still
237 possible to create fixed_wide_ints that have precisions greater than
238 MAX_BITSIZE_MODE_ANY_INT. This can be useful when representing a
239 double-width multiplication result, for example. */
240#define WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64) \
241 ((MAX_BITSIZE_MODE_ANY_INT(64*(8)) + HOST_BITS_PER_WIDE_INT64) / HOST_BITS_PER_WIDE_INT64)
242
243#define WIDE_INT_MAX_PRECISION((((64*(8)) + 64) / 64) * 64) (WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64) * HOST_BITS_PER_WIDE_INT64)
244
245/* This is the max size of any pointer on any machine. It does not
246 seem to be as easy to sniff this out of the machine description as
247 it is for MAX_BITSIZE_MODE_ANY_INT since targets may support
248 multiple address sizes and may have different address sizes for
249 different address spaces. However, currently the largest pointer
250 on any platform is 64 bits. When that changes, then it is likely
251 that a target hook should be defined so that targets can make this
252 value larger for those targets. */
253#define ADDR_MAX_BITSIZE64 64
254
255/* This is the internal precision used when doing any address
256 arithmetic. The '4' is really 3 + 1. Three of the bits are for
257 the number of extra bits needed to do bit addresses and the other bit
258 is to allow everything to be signed without loosing any precision.
259 Then everything is rounded up to the next HWI for efficiency. */
260#define ADDR_MAX_PRECISION((64 + 4 + 64 - 1) & ~(64 - 1)) \
261 ((ADDR_MAX_BITSIZE64 + 4 + HOST_BITS_PER_WIDE_INT64 - 1) \
262 & ~(HOST_BITS_PER_WIDE_INT64 - 1))
263
264/* The number of HWIs needed to store an offset_int. */
265#define OFFSET_INT_ELTS(((64 + 4 + 64 - 1) & ~(64 - 1)) / 64) (ADDR_MAX_PRECISION((64 + 4 + 64 - 1) & ~(64 - 1)) / HOST_BITS_PER_WIDE_INT64)
266
267/* The type of result produced by a binary operation on types T1 and T2.
268 Defined purely for brevity. */
269#define WI_BINARY_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::result_type \
270 typename wi::binary_traits <T1, T2>::result_type
271
272/* Likewise for binary operators, which excludes the case in which neither
273 T1 nor T2 is a wide-int-based type. */
274#define WI_BINARY_OPERATOR_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::operator_result \
275 typename wi::binary_traits <T1, T2>::operator_result
276
277/* The type of result produced by T1 << T2. Leads to substitution failure
278 if the operation isn't supported. Defined purely for brevity. */
279#define WI_SIGNED_SHIFT_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::signed_shift_result_type \
280 typename wi::binary_traits <T1, T2>::signed_shift_result_type
281
282/* The type of result produced by a sign-agnostic binary predicate on
283 types T1 and T2. This is bool if wide-int operations make sense for
284 T1 and T2 and leads to substitution failure otherwise. */
285#define WI_BINARY_PREDICATE_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::predicate_result \
286 typename wi::binary_traits <T1, T2>::predicate_result
287
288/* The type of result produced by a signed binary predicate on types T1 and T2.
289 This is bool if signed comparisons make sense for T1 and T2 and leads to
290 substitution failure otherwise. */
291#define WI_SIGNED_BINARY_PREDICATE_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::signed_predicate_result \
292 typename wi::binary_traits <T1, T2>::signed_predicate_result
293
294/* The type of result produced by a unary operation on type T. */
295#define WI_UNARY_RESULT(T)typename wi::binary_traits <T, T>::result_type \
296 typename wi::binary_traits <T, T>::result_type
297
298/* Define a variable RESULT to hold the result of a binary operation on
299 X and Y, which have types T1 and T2 respectively. Define VAL to
300 point to the blocks of RESULT. Once the user of the macro has
301 filled in VAL, it should call RESULT.set_len to set the number
302 of initialized blocks. */
303#define WI_BINARY_RESULT_VAR(RESULT, VAL, T1, X, T2, Y)typename wi::binary_traits <T1, T2>::result_type RESULT
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (X, Y); long *VAL = RESULT
.write_val ()
\
304 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type RESULT = \
305 wi::int_traits <WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type>::get_binary_result (X, Y); \
306 HOST_WIDE_INTlong *VAL = RESULT.write_val ()
307
308/* Similar for the result of a unary operation on X, which has type T. */
309#define WI_UNARY_RESULT_VAR(RESULT, VAL, T, X)typename wi::binary_traits <T, T>::result_type RESULT =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (X, X); long *VAL = RESULT
.write_val ()
\
310 WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type RESULT = \
311 wi::int_traits <WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type>::get_binary_result (X, X); \
312 HOST_WIDE_INTlong *VAL = RESULT.write_val ()
313
314template <typename T> class generic_wide_int;
315template <int N> class fixed_wide_int_storage;
316class wide_int_storage;
317
318/* An N-bit integer. Until we can use typedef templates, use this instead. */
319#define FIXED_WIDE_INT(N)generic_wide_int < fixed_wide_int_storage <N> > \
320 generic_wide_int < fixed_wide_int_storage <N> >
321
322typedef generic_wide_int <wide_int_storage> wide_int;
323typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION)generic_wide_int < fixed_wide_int_storage <((64 + 4 + 64
- 1) & ~(64 - 1))> >
offset_int;
324typedef FIXED_WIDE_INT (WIDE_INT_MAX_PRECISION)generic_wide_int < fixed_wide_int_storage <((((64*(8)) +
64) / 64) * 64)> >
widest_int;
325/* Spelled out explicitly (rather than through FIXED_WIDE_INT)
326 so as not to confuse gengtype. */
327typedef generic_wide_int < fixed_wide_int_storage <WIDE_INT_MAX_PRECISION((((64*(8)) + 64) / 64) * 64) * 2> > widest2_int;
328
329/* wi::storage_ref can be a reference to a primitive type,
330 so this is the conservatively-correct setting. */
331template <bool SE, bool HDP = true>
332class wide_int_ref_storage;
333
334typedef generic_wide_int <wide_int_ref_storage <false> > wide_int_ref;
335
336/* This can be used instead of wide_int_ref if the referenced value is
337 known to have type T. It carries across properties of T's representation,
338 such as whether excess upper bits in a HWI are defined, and can therefore
339 help avoid redundant work.
340
341 The macro could be replaced with a template typedef, once we're able
342 to use those. */
343#define WIDE_INT_REF_FOR(T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
\
344 generic_wide_int \
345 <wide_int_ref_storage <wi::int_traits <T>::is_sign_extended, \
346 wi::int_traits <T>::host_dependent_precision> >
347
348namespace wi
349{
350 /* Operations that calculate overflow do so even for
351 TYPE_OVERFLOW_WRAPS types. For example, adding 1 to +MAX_INT in
352 an unsigned int is 0 and does not overflow in C/C++, but wi::add
353 will set the overflow argument in case it's needed for further
354 analysis.
355
356 For operations that require overflow, these are the different
357 types of overflow. */
358 enum overflow_type {
359 OVF_NONE = 0,
360 OVF_UNDERFLOW = -1,
361 OVF_OVERFLOW = 1,
362 /* There was an overflow, but we are unsure whether it was an
363 overflow or an underflow. */
364 OVF_UNKNOWN = 2
365 };
366
367 /* Classifies an integer based on its precision. */
368 enum precision_type {
369 /* The integer has both a precision and defined signedness. This allows
370 the integer to be converted to any width, since we know whether to fill
371 any extra bits with zeros or signs. */
372 FLEXIBLE_PRECISION,
373
374 /* The integer has a variable precision but no defined signedness. */
375 VAR_PRECISION,
376
377 /* The integer has a constant precision (known at GCC compile time)
378 and is signed. */
379 CONST_PRECISION
380 };
381
382 /* This class, which has no default implementation, is expected to
383 provide the following members:
384
385 static const enum precision_type precision_type;
386 Classifies the type of T.
387
388 static const unsigned int precision;
389 Only defined if precision_type == CONST_PRECISION. Specifies the
390 precision of all integers of type T.
391
392 static const bool host_dependent_precision;
393 True if the precision of T depends (or can depend) on the host.
394
395 static unsigned int get_precision (const T &x)
396 Return the number of bits in X.
397
398 static wi::storage_ref *decompose (HOST_WIDE_INT *scratch,
399 unsigned int precision, const T &x)
400 Decompose X as a PRECISION-bit integer, returning the associated
401 wi::storage_ref. SCRATCH is available as scratch space if needed.
402 The routine should assert that PRECISION is acceptable. */
403 template <typename T> struct int_traits;
404
405 /* This class provides a single type, result_type, which specifies the
406 type of integer produced by a binary operation whose inputs have
407 types T1 and T2. The definition should be symmetric. */
408 template <typename T1, typename T2,
409 enum precision_type P1 = int_traits <T1>::precision_type,
410 enum precision_type P2 = int_traits <T2>::precision_type>
411 struct binary_traits;
412
413 /* Specify the result type for each supported combination of binary
414 inputs. Note that CONST_PRECISION and VAR_PRECISION cannot be
415 mixed, in order to give stronger type checking. When both inputs
416 are CONST_PRECISION, they must have the same precision. */
417 template <typename T1, typename T2>
418 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
419 {
420 typedef widest_int result_type;
421 /* Don't define operators for this combination. */
422 };
423
424 template <typename T1, typename T2>
425 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION>
426 {
427 typedef wide_int result_type;
428 typedef result_type operator_result;
429 typedef bool predicate_result;
430 };
431
432 template <typename T1, typename T2>
433 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION>
434 {
435 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
436 so as not to confuse gengtype. */
437 typedef generic_wide_int < fixed_wide_int_storage
438 <int_traits <T2>::precision> > result_type;
439 typedef result_type operator_result;
440 typedef bool predicate_result;
441 typedef result_type signed_shift_result_type;
442 typedef bool signed_predicate_result;
443 };
444
445 template <typename T1, typename T2>
446 struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION>
447 {
448 typedef wide_int result_type;
449 typedef result_type operator_result;
450 typedef bool predicate_result;
451 };
452
453 template <typename T1, typename T2>
454 struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION>
455 {
456 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
457 so as not to confuse gengtype. */
458 typedef generic_wide_int < fixed_wide_int_storage
459 <int_traits <T1>::precision> > result_type;
460 typedef result_type operator_result;
461 typedef bool predicate_result;
462 typedef result_type signed_shift_result_type;
463 typedef bool signed_predicate_result;
464 };
465
466 template <typename T1, typename T2>
467 struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION>
468 {
469 STATIC_ASSERT (int_traits <T1>::precision == int_traits <T2>::precision)static_assert ((int_traits <T1>::precision == int_traits
<T2>::precision), "int_traits <T1>::precision == int_traits <T2>::precision"
)
;
470 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
471 so as not to confuse gengtype. */
472 typedef generic_wide_int < fixed_wide_int_storage
473 <int_traits <T1>::precision> > result_type;
474 typedef result_type operator_result;
475 typedef bool predicate_result;
476 typedef result_type signed_shift_result_type;
477 typedef bool signed_predicate_result;
478 };
479
480 template <typename T1, typename T2>
481 struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION>
482 {
483 typedef wide_int result_type;
484 typedef result_type operator_result;
485 typedef bool predicate_result;
486 };
487}
488
489/* Public functions for querying and operating on integers. */
490namespace wi
491{
492 template <typename T>
493 unsigned int get_precision (const T &);
494
495 template <typename T1, typename T2>
496 unsigned int get_binary_precision (const T1 &, const T2 &);
497
498 template <typename T1, typename T2>
499 void copy (T1 &, const T2 &);
500
501#define UNARY_PREDICATE \
502 template <typename T> bool
503#define UNARY_FUNCTION \
504 template <typename T> WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
505#define BINARY_PREDICATE \
506 template <typename T1, typename T2> bool
507#define BINARY_FUNCTION \
508 template <typename T1, typename T2> WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
509#define SHIFT_FUNCTION \
510 template <typename T1, typename T2> WI_UNARY_RESULT (T1)typename wi::binary_traits <T1, T1>::result_type
511
512 UNARY_PREDICATE fits_shwi_p (const T &);
513 UNARY_PREDICATE fits_uhwi_p (const T &);
514 UNARY_PREDICATE neg_p (const T &, signop = SIGNED);
515
516 template <typename T>
517 HOST_WIDE_INTlong sign_mask (const T &);
518
519 BINARY_PREDICATE eq_p (const T1 &, const T2 &);
520 BINARY_PREDICATE ne_p (const T1 &, const T2 &);
521 BINARY_PREDICATE lt_p (const T1 &, const T2 &, signop);
522 BINARY_PREDICATE lts_p (const T1 &, const T2 &);
523 BINARY_PREDICATE ltu_p (const T1 &, const T2 &);
524 BINARY_PREDICATE le_p (const T1 &, const T2 &, signop);
525 BINARY_PREDICATE les_p (const T1 &, const T2 &);
526 BINARY_PREDICATE leu_p (const T1 &, const T2 &);
527 BINARY_PREDICATE gt_p (const T1 &, const T2 &, signop);
528 BINARY_PREDICATE gts_p (const T1 &, const T2 &);
529 BINARY_PREDICATE gtu_p (const T1 &, const T2 &);
530 BINARY_PREDICATE ge_p (const T1 &, const T2 &, signop);
531 BINARY_PREDICATE ges_p (const T1 &, const T2 &);
532 BINARY_PREDICATE geu_p (const T1 &, const T2 &);
533
534 template <typename T1, typename T2>
535 int cmp (const T1 &, const T2 &, signop);
536
537 template <typename T1, typename T2>
538 int cmps (const T1 &, const T2 &);
539
540 template <typename T1, typename T2>
541 int cmpu (const T1 &, const T2 &);
542
543 UNARY_FUNCTION bit_not (const T &);
544 UNARY_FUNCTION neg (const T &);
545 UNARY_FUNCTION neg (const T &, overflow_type *);
546 UNARY_FUNCTION abs (const T &);
547 UNARY_FUNCTION ext (const T &, unsigned int, signop);
548 UNARY_FUNCTION sext (const T &, unsigned int);
549 UNARY_FUNCTION zext (const T &, unsigned int);
550 UNARY_FUNCTION set_bit (const T &, unsigned int);
551
552 BINARY_FUNCTION min (const T1 &, const T2 &, signop);
553 BINARY_FUNCTION smin (const T1 &, const T2 &);
554 BINARY_FUNCTION umin (const T1 &, const T2 &);
555 BINARY_FUNCTION max (const T1 &, const T2 &, signop);
556 BINARY_FUNCTION smax (const T1 &, const T2 &);
557 BINARY_FUNCTION umax (const T1 &, const T2 &);
558
559 BINARY_FUNCTION bit_and (const T1 &, const T2 &);
560 BINARY_FUNCTION bit_and_not (const T1 &, const T2 &);
561 BINARY_FUNCTION bit_or (const T1 &, const T2 &);
562 BINARY_FUNCTION bit_or_not (const T1 &, const T2 &);
563 BINARY_FUNCTION bit_xor (const T1 &, const T2 &);
564 BINARY_FUNCTION add (const T1 &, const T2 &);
565 BINARY_FUNCTION add (const T1 &, const T2 &, signop, overflow_type *);
566 BINARY_FUNCTION sub (const T1 &, const T2 &);
567 BINARY_FUNCTION sub (const T1 &, const T2 &, signop, overflow_type *);
568 BINARY_FUNCTION mul (const T1 &, const T2 &);
569 BINARY_FUNCTION mul (const T1 &, const T2 &, signop, overflow_type *);
570 BINARY_FUNCTION smul (const T1 &, const T2 &, overflow_type *);
571 BINARY_FUNCTION umul (const T1 &, const T2 &, overflow_type *);
572 BINARY_FUNCTION mul_high (const T1 &, const T2 &, signop);
573 BINARY_FUNCTION div_trunc (const T1 &, const T2 &, signop,
574 overflow_type * = 0);
575 BINARY_FUNCTION sdiv_trunc (const T1 &, const T2 &);
576 BINARY_FUNCTION udiv_trunc (const T1 &, const T2 &);
577 BINARY_FUNCTION div_floor (const T1 &, const T2 &, signop,
578 overflow_type * = 0);
579 BINARY_FUNCTION udiv_floor (const T1 &, const T2 &);
580 BINARY_FUNCTION sdiv_floor (const T1 &, const T2 &);
581 BINARY_FUNCTION div_ceil (const T1 &, const T2 &, signop,
582 overflow_type * = 0);
583 BINARY_FUNCTION udiv_ceil (const T1 &, const T2 &);
584 BINARY_FUNCTION div_round (const T1 &, const T2 &, signop,
585 overflow_type * = 0);
586 BINARY_FUNCTION divmod_trunc (const T1 &, const T2 &, signop,
587 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type *);
588 BINARY_FUNCTION gcd (const T1 &, const T2 &, signop = UNSIGNED);
589 BINARY_FUNCTION mod_trunc (const T1 &, const T2 &, signop,
590 overflow_type * = 0);
591 BINARY_FUNCTION smod_trunc (const T1 &, const T2 &);
592 BINARY_FUNCTION umod_trunc (const T1 &, const T2 &);
593 BINARY_FUNCTION mod_floor (const T1 &, const T2 &, signop,
594 overflow_type * = 0);
595 BINARY_FUNCTION umod_floor (const T1 &, const T2 &);
596 BINARY_FUNCTION mod_ceil (const T1 &, const T2 &, signop,
597 overflow_type * = 0);
598 BINARY_FUNCTION mod_round (const T1 &, const T2 &, signop,
599 overflow_type * = 0);
600
601 template <typename T1, typename T2>
602 bool multiple_of_p (const T1 &, const T2 &, signop);
603
604 template <typename T1, typename T2>
605 bool multiple_of_p (const T1 &, const T2 &, signop,
606 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type *);
607
608 SHIFT_FUNCTION lshift (const T1 &, const T2 &);
609 SHIFT_FUNCTION lrshift (const T1 &, const T2 &);
610 SHIFT_FUNCTION arshift (const T1 &, const T2 &);
611 SHIFT_FUNCTION rshift (const T1 &, const T2 &, signop sgn);
612 SHIFT_FUNCTION lrotate (const T1 &, const T2 &, unsigned int = 0);
613 SHIFT_FUNCTION rrotate (const T1 &, const T2 &, unsigned int = 0);
614
615#undef SHIFT_FUNCTION
616#undef BINARY_PREDICATE
617#undef BINARY_FUNCTION
618#undef UNARY_PREDICATE
619#undef UNARY_FUNCTION
620
621 bool only_sign_bit_p (const wide_int_ref &, unsigned int);
622 bool only_sign_bit_p (const wide_int_ref &);
623 int clz (const wide_int_ref &);
624 int clrsb (const wide_int_ref &);
625 int ctz (const wide_int_ref &);
626 int exact_log2 (const wide_int_ref &);
627 int floor_log2 (const wide_int_ref &);
628 int ffs (const wide_int_ref &);
629 int popcount (const wide_int_ref &);
630 int parity (const wide_int_ref &);
631
632 template <typename T>
633 unsigned HOST_WIDE_INTlong extract_uhwi (const T &, unsigned int, unsigned int);
634
635 template <typename T>
636 unsigned int min_precision (const T &, signop);
637
638 static inline void accumulate_overflow (overflow_type &, overflow_type);
639}
640
641namespace wi
642{
643 /* Contains the components of a decomposed integer for easy, direct
644 access. */
645 class storage_ref
646 {
647 public:
648 storage_ref () {}
649 storage_ref (const HOST_WIDE_INTlong *, unsigned int, unsigned int);
650
651 const HOST_WIDE_INTlong *val;
652 unsigned int len;
653 unsigned int precision;
654
655 /* Provide enough trappings for this class to act as storage for
656 generic_wide_int. */
657 unsigned int get_len () const;
658 unsigned int get_precision () const;
659 const HOST_WIDE_INTlong *get_val () const;
660 };
661}
662
663inline::wi::storage_ref::storage_ref (const HOST_WIDE_INTlong *val_in,
664 unsigned int len_in,
665 unsigned int precision_in)
666 : val (val_in), len (len_in), precision (precision_in)
667{
668}
669
670inline unsigned int
671wi::storage_ref::get_len () const
672{
673 return len;
674}
675
676inline unsigned int
677wi::storage_ref::get_precision () const
678{
679 return precision;
680}
681
682inline const HOST_WIDE_INTlong *
683wi::storage_ref::get_val () const
684{
685 return val;
686}
687
688/* This class defines an integer type using the storage provided by the
689 template argument. The storage class must provide the following
690 functions:
691
692 unsigned int get_precision () const
693 Return the number of bits in the integer.
694
695 HOST_WIDE_INT *get_val () const
696 Return a pointer to the array of blocks that encodes the integer.
697
698 unsigned int get_len () const
699 Return the number of blocks in get_val (). If this is smaller
700 than the number of blocks implied by get_precision (), the
701 remaining blocks are sign extensions of block get_len () - 1.
702
703 Although not required by generic_wide_int itself, writable storage
704 classes can also provide the following functions:
705
706 HOST_WIDE_INT *write_val ()
707 Get a modifiable version of get_val ()
708
709 unsigned int set_len (unsigned int len)
710 Set the value returned by get_len () to LEN. */
711template <typename storage>
712class GTY(()) generic_wide_int : public storage
713{
714public:
715 generic_wide_int ();
716
717 template <typename T>
718 generic_wide_int (const T &);
719
720 template <typename T>
721 generic_wide_int (const T &, unsigned int);
722
723 /* Conversions. */
724 HOST_WIDE_INTlong to_shwi (unsigned int) const;
725 HOST_WIDE_INTlong to_shwi () const;
726 unsigned HOST_WIDE_INTlong to_uhwi (unsigned int) const;
727 unsigned HOST_WIDE_INTlong to_uhwi () const;
728 HOST_WIDE_INTlong to_short_addr () const;
729
730 /* Public accessors for the interior of a wide int. */
731 HOST_WIDE_INTlong sign_mask () const;
732 HOST_WIDE_INTlong elt (unsigned int) const;
733 HOST_WIDE_INTlong sext_elt (unsigned int) const;
734 unsigned HOST_WIDE_INTlong ulow () const;
735 unsigned HOST_WIDE_INTlong uhigh () const;
736 HOST_WIDE_INTlong slow () const;
737 HOST_WIDE_INTlong shigh () const;
738
739 template <typename T>
740 generic_wide_int &operator = (const T &);
741
742#define ASSIGNMENT_OPERATOR(OP, F) \
743 template <typename T> \
744 generic_wide_int &OP (const T &c) { return (*this = wi::F (*this, c)); }
745
746/* Restrict these to cases where the shift operator is defined. */
747#define SHIFT_ASSIGNMENT_OPERATOR(OP, OP2) \
748 template <typename T> \
749 generic_wide_int &OP (const T &c) { return (*this = *this OP2 c); }
750
751#define INCDEC_OPERATOR(OP, DELTA) \
752 generic_wide_int &OP () { *this += DELTA; return *this; }
753
754 ASSIGNMENT_OPERATOR (operator &=, bit_and)
755 ASSIGNMENT_OPERATOR (operator |=, bit_or)
756 ASSIGNMENT_OPERATOR (operator ^=, bit_xor)
757 ASSIGNMENT_OPERATOR (operator +=, add)
758 ASSIGNMENT_OPERATOR (operator -=, sub)
759 ASSIGNMENT_OPERATOR (operator *=, mul)
760 ASSIGNMENT_OPERATOR (operator <<=, lshift)
761 SHIFT_ASSIGNMENT_OPERATOR (operator >>=, >>)
762 INCDEC_OPERATOR (operator ++, 1)
763 INCDEC_OPERATOR (operator --, -1)
764
765#undef SHIFT_ASSIGNMENT_OPERATOR
766#undef ASSIGNMENT_OPERATOR
767#undef INCDEC_OPERATOR
768
769 /* Debugging functions. */
770 void dump () const;
771
772 static const bool is_sign_extended
773 = wi::int_traits <generic_wide_int <storage> >::is_sign_extended;
774};
775
776template <typename storage>
777inline generic_wide_int <storage>::generic_wide_int () {}
778
779template <typename storage>
780template <typename T>
781inline generic_wide_int <storage>::generic_wide_int (const T &x)
782 : storage (x)
783{
784}
785
786template <typename storage>
787template <typename T>
788inline generic_wide_int <storage>::generic_wide_int (const T &x,
789 unsigned int precision)
790 : storage (x, precision)
791{
792}
793
794/* Return THIS as a signed HOST_WIDE_INT, sign-extending from PRECISION.
795 If THIS does not fit in PRECISION, the information is lost. */
796template <typename storage>
797inline HOST_WIDE_INTlong
798generic_wide_int <storage>::to_shwi (unsigned int precision) const
799{
800 if (precision < HOST_BITS_PER_WIDE_INT64)
801 return sext_hwi (this->get_val ()[0], precision);
802 else
803 return this->get_val ()[0];
804}
805
806/* Return THIS as a signed HOST_WIDE_INT, in its natural precision. */
807template <typename storage>
808inline HOST_WIDE_INTlong
809generic_wide_int <storage>::to_shwi () const
810{
811 if (is_sign_extended)
812 return this->get_val ()[0];
813 else
814 return to_shwi (this->get_precision ());
815}
816
817/* Return THIS as an unsigned HOST_WIDE_INT, zero-extending from
818 PRECISION. If THIS does not fit in PRECISION, the information
819 is lost. */
820template <typename storage>
821inline unsigned HOST_WIDE_INTlong
822generic_wide_int <storage>::to_uhwi (unsigned int precision) const
823{
824 if (precision
23.1
'precision' is < HOST_BITS_PER_WIDE_INT
23.1
'precision' is < HOST_BITS_PER_WIDE_INT
23.1
'precision' is < HOST_BITS_PER_WIDE_INT
< HOST_BITS_PER_WIDE_INT64)
24
Taking true branch
825 return zext_hwi (this->get_val ()[0], precision);
25
Calling 'zext_hwi'
29
Returning from 'zext_hwi'
30
Returning zero
826 else
827 return this->get_val ()[0];
828}
829
830/* Return THIS as an signed HOST_WIDE_INT, in its natural precision. */
831template <typename storage>
832inline unsigned HOST_WIDE_INTlong
833generic_wide_int <storage>::to_uhwi () const
834{
835 return to_uhwi (this->get_precision ());
23
Calling 'generic_wide_int::to_uhwi'
31
Returning from 'generic_wide_int::to_uhwi'
32
Returning zero
836}
837
838/* TODO: The compiler is half converted from using HOST_WIDE_INT to
839 represent addresses to using offset_int to represent addresses.
840 We use to_short_addr at the interface from new code to old,
841 unconverted code. */
842template <typename storage>
843inline HOST_WIDE_INTlong
844generic_wide_int <storage>::to_short_addr () const
845{
846 return this->get_val ()[0];
847}
848
849/* Return the implicit value of blocks above get_len (). */
850template <typename storage>
851inline HOST_WIDE_INTlong
852generic_wide_int <storage>::sign_mask () const
853{
854 unsigned int len = this->get_len ();
855 gcc_assert (len > 0)((void)(!(len > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 855, __FUNCTION__), 0 : 0))
;
856
857 unsigned HOST_WIDE_INTlong high = this->get_val ()[len - 1];
858 if (!is_sign_extended)
859 {
860 unsigned int precision = this->get_precision ();
861 int excess = len * HOST_BITS_PER_WIDE_INT64 - precision;
862 if (excess > 0)
863 high <<= excess;
864 }
865 return (HOST_WIDE_INTlong) (high) < 0 ? -1 : 0;
866}
867
868/* Return the signed value of the least-significant explicitly-encoded
869 block. */
870template <typename storage>
871inline HOST_WIDE_INTlong
872generic_wide_int <storage>::slow () const
873{
874 return this->get_val ()[0];
875}
876
877/* Return the signed value of the most-significant explicitly-encoded
878 block. */
879template <typename storage>
880inline HOST_WIDE_INTlong
881generic_wide_int <storage>::shigh () const
882{
883 return this->get_val ()[this->get_len () - 1];
884}
885
886/* Return the unsigned value of the least-significant
887 explicitly-encoded block. */
888template <typename storage>
889inline unsigned HOST_WIDE_INTlong
890generic_wide_int <storage>::ulow () const
891{
892 return this->get_val ()[0];
893}
894
895/* Return the unsigned value of the most-significant
896 explicitly-encoded block. */
897template <typename storage>
898inline unsigned HOST_WIDE_INTlong
899generic_wide_int <storage>::uhigh () const
900{
901 return this->get_val ()[this->get_len () - 1];
902}
903
904/* Return block I, which might be implicitly or explicit encoded. */
905template <typename storage>
906inline HOST_WIDE_INTlong
907generic_wide_int <storage>::elt (unsigned int i) const
908{
909 if (i >= this->get_len ())
910 return sign_mask ();
911 else
912 return this->get_val ()[i];
913}
914
915/* Like elt, but sign-extend beyond the upper bit, instead of returning
916 the raw encoding. */
917template <typename storage>
918inline HOST_WIDE_INTlong
919generic_wide_int <storage>::sext_elt (unsigned int i) const
920{
921 HOST_WIDE_INTlong elt_i = elt (i);
922 if (!is_sign_extended)
923 {
924 unsigned int precision = this->get_precision ();
925 unsigned int lsb = i * HOST_BITS_PER_WIDE_INT64;
926 if (precision - lsb < HOST_BITS_PER_WIDE_INT64)
927 elt_i = sext_hwi (elt_i, precision - lsb);
928 }
929 return elt_i;
930}
931
932template <typename storage>
933template <typename T>
934inline generic_wide_int <storage> &
935generic_wide_int <storage>::operator = (const T &x)
936{
937 storage::operator = (x);
938 return *this;
939}
940
941/* Dump the contents of the integer to stderr, for debugging. */
942template <typename storage>
943void
944generic_wide_int <storage>::dump () const
945{
946 unsigned int len = this->get_len ();
947 const HOST_WIDE_INTlong *val = this->get_val ();
948 unsigned int precision = this->get_precision ();
949 fprintf (stderrstderr, "[");
950 if (len * HOST_BITS_PER_WIDE_INT64 < precision)
951 fprintf (stderrstderr, "...,");
952 for (unsigned int i = 0; i < len - 1; ++i)
953 fprintf (stderrstderr, HOST_WIDE_INT_PRINT_HEX"%#" "l" "x" ",", val[len - 1 - i]);
954 fprintf (stderrstderr, HOST_WIDE_INT_PRINT_HEX"%#" "l" "x" "], precision = %d\n",
955 val[0], precision);
956}
957
958namespace wi
959{
960 template <typename storage>
961 struct int_traits < generic_wide_int <storage> >
962 : public wi::int_traits <storage>
963 {
964 static unsigned int get_precision (const generic_wide_int <storage> &);
965 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int,
966 const generic_wide_int <storage> &);
967 };
968}
969
970template <typename storage>
971inline unsigned int
972wi::int_traits < generic_wide_int <storage> >::
973get_precision (const generic_wide_int <storage> &x)
974{
975 return x.get_precision ();
976}
977
978template <typename storage>
979inline wi::storage_ref
980wi::int_traits < generic_wide_int <storage> >::
981decompose (HOST_WIDE_INTlong *, unsigned int precision,
982 const generic_wide_int <storage> &x)
983{
984 gcc_checking_assert (precision == x.get_precision ())((void)(!(precision == x.get_precision ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 984, __FUNCTION__), 0 : 0))
;
985 return wi::storage_ref (x.get_val (), x.get_len (), precision);
986}
987
988/* Provide the storage for a wide_int_ref. This acts like a read-only
989 wide_int, with the optimization that VAL is normally a pointer to
990 another integer's storage, so that no array copy is needed. */
991template <bool SE, bool HDP>
992class wide_int_ref_storage : public wi::storage_ref
993{
994private:
995 /* Scratch space that can be used when decomposing the original integer.
996 It must live as long as this object. */
997 HOST_WIDE_INTlong scratch[2];
998
999public:
1000 wide_int_ref_storage () {}
1001
1002 wide_int_ref_storage (const wi::storage_ref &);
1003
1004 template <typename T>
1005 wide_int_ref_storage (const T &);
1006
1007 template <typename T>
1008 wide_int_ref_storage (const T &, unsigned int);
1009};
1010
1011/* Create a reference from an existing reference. */
1012template <bool SE, bool HDP>
1013inline wide_int_ref_storage <SE, HDP>::
1014wide_int_ref_storage (const wi::storage_ref &x)
1015 : storage_ref (x)
1016{}
1017
1018/* Create a reference to integer X in its natural precision. Note
1019 that the natural precision is host-dependent for primitive
1020 types. */
1021template <bool SE, bool HDP>
1022template <typename T>
1023inline wide_int_ref_storage <SE, HDP>::wide_int_ref_storage (const T &x)
1024 : storage_ref (wi::int_traits <T>::decompose (scratch,
1025 wi::get_precision (x), x))
1026{
1027}
1028
1029/* Create a reference to integer X in precision PRECISION. */
1030template <bool SE, bool HDP>
1031template <typename T>
1032inline wide_int_ref_storage <SE, HDP>::
1033wide_int_ref_storage (const T &x, unsigned int precision)
1034 : storage_ref (wi::int_traits <T>::decompose (scratch, precision, x))
1035{
1036}
1037
1038namespace wi
1039{
1040 template <bool SE, bool HDP>
1041 struct int_traits <wide_int_ref_storage <SE, HDP> >
1042 {
1043 static const enum precision_type precision_type = VAR_PRECISION;
1044 static const bool host_dependent_precision = HDP;
1045 static const bool is_sign_extended = SE;
1046 };
1047}
1048
1049namespace wi
1050{
1051 unsigned int force_to_size (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1052 unsigned int, unsigned int, unsigned int,
1053 signop sgn);
1054 unsigned int from_array (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1055 unsigned int, unsigned int, bool = true);
1056}
1057
1058/* The storage used by wide_int. */
1059class GTY(()) wide_int_storage
1060{
1061private:
1062 HOST_WIDE_INTlong val[WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64)];
1063 unsigned int len;
1064 unsigned int precision;
1065
1066public:
1067 wide_int_storage ();
1068 template <typename T>
1069 wide_int_storage (const T &);
1070
1071 /* The standard generic_wide_int storage methods. */
1072 unsigned int get_precision () const;
1073 const HOST_WIDE_INTlong *get_val () const;
1074 unsigned int get_len () const;
1075 HOST_WIDE_INTlong *write_val ();
1076 void set_len (unsigned int, bool = false);
1077
1078 template <typename T>
1079 wide_int_storage &operator = (const T &);
1080
1081 static wide_int from (const wide_int_ref &, unsigned int, signop);
1082 static wide_int from_array (const HOST_WIDE_INTlong *, unsigned int,
1083 unsigned int, bool = true);
1084 static wide_int create (unsigned int);
1085
1086 /* FIXME: target-dependent, so should disappear. */
1087 wide_int bswap () const;
1088};
1089
1090namespace wi
1091{
1092 template <>
1093 struct int_traits <wide_int_storage>
1094 {
1095 static const enum precision_type precision_type = VAR_PRECISION;
1096 /* Guaranteed by a static assert in the wide_int_storage constructor. */
1097 static const bool host_dependent_precision = false;
1098 static const bool is_sign_extended = true;
1099 template <typename T1, typename T2>
1100 static wide_int get_binary_result (const T1 &, const T2 &);
1101 };
1102}
1103
1104inline wide_int_storage::wide_int_storage () {}
1105
1106/* Initialize the storage from integer X, in its natural precision.
1107 Note that we do not allow integers with host-dependent precision
1108 to become wide_ints; wide_ints must always be logically independent
1109 of the host. */
1110template <typename T>
1111inline wide_int_storage::wide_int_storage (const T &x)
1112{
1113 { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision)static_assert ((!wi::int_traits<T>::host_dependent_precision
), "!wi::int_traits<T>::host_dependent_precision")
; }
1114 { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION)static_assert ((wi::int_traits<T>::precision_type != wi
::CONST_PRECISION), "wi::int_traits<T>::precision_type != wi::CONST_PRECISION"
)
; }
1115 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1116 precision = xi.precision;
1117 wi::copy (*this, xi);
1118}
1119
1120template <typename T>
1121inline wide_int_storage&
1122wide_int_storage::operator = (const T &x)
1123{
1124 { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision)static_assert ((!wi::int_traits<T>::host_dependent_precision
), "!wi::int_traits<T>::host_dependent_precision")
; }
1125 { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION)static_assert ((wi::int_traits<T>::precision_type != wi
::CONST_PRECISION), "wi::int_traits<T>::precision_type != wi::CONST_PRECISION"
)
; }
1126 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1127 precision = xi.precision;
1128 wi::copy (*this, xi);
1129 return *this;
1130}
1131
1132inline unsigned int
1133wide_int_storage::get_precision () const
1134{
1135 return precision;
1136}
1137
1138inline const HOST_WIDE_INTlong *
1139wide_int_storage::get_val () const
1140{
1141 return val;
1142}
1143
1144inline unsigned int
1145wide_int_storage::get_len () const
1146{
1147 return len;
1148}
1149
1150inline HOST_WIDE_INTlong *
1151wide_int_storage::write_val ()
1152{
1153 return val;
1154}
1155
1156inline void
1157wide_int_storage::set_len (unsigned int l, bool is_sign_extended)
1158{
1159 len = l;
1160 if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT64 > precision)
1161 val[len - 1] = sext_hwi (val[len - 1],
1162 precision % HOST_BITS_PER_WIDE_INT64);
1163}
1164
1165/* Treat X as having signedness SGN and convert it to a PRECISION-bit
1166 number. */
1167inline wide_int
1168wide_int_storage::from (const wide_int_ref &x, unsigned int precision,
1169 signop sgn)
1170{
1171 wide_int result = wide_int::create (precision);
1172 result.set_len (wi::force_to_size (result.write_val (), x.val, x.len,
1173 x.precision, precision, sgn));
1174 return result;
1175}
1176
1177/* Create a wide_int from the explicit block encoding given by VAL and
1178 LEN. PRECISION is the precision of the integer. NEED_CANON_P is
1179 true if the encoding may have redundant trailing blocks. */
1180inline wide_int
1181wide_int_storage::from_array (const HOST_WIDE_INTlong *val, unsigned int len,
1182 unsigned int precision, bool need_canon_p)
1183{
1184 wide_int result = wide_int::create (precision);
1185 result.set_len (wi::from_array (result.write_val (), val, len, precision,
1186 need_canon_p));
1187 return result;
1188}
1189
1190/* Return an uninitialized wide_int with precision PRECISION. */
1191inline wide_int
1192wide_int_storage::create (unsigned int precision)
1193{
1194 wide_int x;
1195 x.precision = precision;
1196 return x;
1197}
1198
1199template <typename T1, typename T2>
1200inline wide_int
1201wi::int_traits <wide_int_storage>::get_binary_result (const T1 &x, const T2 &y)
1202{
1203 /* This shouldn't be used for two flexible-precision inputs. */
1204 STATIC_ASSERT (wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISIONstatic_assert ((wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION
|| wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION
), "wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION"
)
1205 || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION)static_assert ((wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION
|| wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION
), "wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION"
)
;
1206 if (wi::int_traits <T1>::precision_type == FLEXIBLE_PRECISION)
1207 return wide_int::create (wi::get_precision (y));
1208 else
1209 return wide_int::create (wi::get_precision (x));
1210}
1211
1212/* The storage used by FIXED_WIDE_INT (N). */
1213template <int N>
1214class GTY(()) fixed_wide_int_storage
1215{
1216private:
1217 HOST_WIDE_INTlong val[(N + HOST_BITS_PER_WIDE_INT64 + 1) / HOST_BITS_PER_WIDE_INT64];
1218 unsigned int len;
1219
1220public:
1221 fixed_wide_int_storage ();
1222 template <typename T>
1223 fixed_wide_int_storage (const T &);
1224
1225 /* The standard generic_wide_int storage methods. */
1226 unsigned int get_precision () const;
1227 const HOST_WIDE_INTlong *get_val () const;
1228 unsigned int get_len () const;
1229 HOST_WIDE_INTlong *write_val ();
1230 void set_len (unsigned int, bool = false);
1231
1232 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > from (const wide_int_ref &, signop);
1233 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > from_array (const HOST_WIDE_INTlong *, unsigned int,
1234 bool = true);
1235};
1236
1237namespace wi
1238{
1239 template <int N>
1240 struct int_traits < fixed_wide_int_storage <N> >
1241 {
1242 static const enum precision_type precision_type = CONST_PRECISION;
1243 static const bool host_dependent_precision = false;
1244 static const bool is_sign_extended = true;
1245 static const unsigned int precision = N;
1246 template <typename T1, typename T2>
1247 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > get_binary_result (const T1 &, const T2 &);
1248 };
1249}
1250
1251template <int N>
1252inline fixed_wide_int_storage <N>::fixed_wide_int_storage () {}
1253
1254/* Initialize the storage from integer X, in precision N. */
1255template <int N>
1256template <typename T>
1257inline fixed_wide_int_storage <N>::fixed_wide_int_storage (const T &x)
1258{
1259 /* Check for type compatibility. We don't want to initialize a
1260 fixed-width integer from something like a wide_int. */
1261 WI_BINARY_RESULT (T, FIXED_WIDE_INT (N))typename wi::binary_traits <T, generic_wide_int < fixed_wide_int_storage
<N> > >::result_type
*assertion ATTRIBUTE_UNUSED__attribute__ ((__unused__));
1262 wi::copy (*this, WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
(x, N));
1263}
1264
1265template <int N>
1266inline unsigned int
1267fixed_wide_int_storage <N>::get_precision () const
1268{
1269 return N;
1270}
1271
1272template <int N>
1273inline const HOST_WIDE_INTlong *
1274fixed_wide_int_storage <N>::get_val () const
1275{
1276 return val;
1277}
1278
1279template <int N>
1280inline unsigned int
1281fixed_wide_int_storage <N>::get_len () const
1282{
1283 return len;
1284}
1285
1286template <int N>
1287inline HOST_WIDE_INTlong *
1288fixed_wide_int_storage <N>::write_val ()
1289{
1290 return val;
1291}
1292
1293template <int N>
1294inline void
1295fixed_wide_int_storage <N>::set_len (unsigned int l, bool)
1296{
1297 len = l;
1298 /* There are no excess bits in val[len - 1]. */
1299 STATIC_ASSERT (N % HOST_BITS_PER_WIDE_INT == 0)static_assert ((N % 64 == 0), "N % HOST_BITS_PER_WIDE_INT == 0"
)
;
1300}
1301
1302/* Treat X as having signedness SGN and convert it to an N-bit number. */
1303template <int N>
1304inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1305fixed_wide_int_storage <N>::from (const wide_int_ref &x, signop sgn)
1306{
1307 FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > result;
1308 result.set_len (wi::force_to_size (result.write_val (), x.val, x.len,
1309 x.precision, N, sgn));
1310 return result;
1311}
1312
1313/* Create a FIXED_WIDE_INT (N) from the explicit block encoding given by
1314 VAL and LEN. NEED_CANON_P is true if the encoding may have redundant
1315 trailing blocks. */
1316template <int N>
1317inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1318fixed_wide_int_storage <N>::from_array (const HOST_WIDE_INTlong *val,
1319 unsigned int len,
1320 bool need_canon_p)
1321{
1322 FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > result;
1323 result.set_len (wi::from_array (result.write_val (), val, len,
1324 N, need_canon_p));
1325 return result;
1326}
1327
1328template <int N>
1329template <typename T1, typename T2>
1330inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1331wi::int_traits < fixed_wide_int_storage <N> >::
1332get_binary_result (const T1 &, const T2 &)
1333{
1334 return FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > ();
1335}
1336
1337/* A reference to one element of a trailing_wide_ints structure. */
1338class trailing_wide_int_storage
1339{
1340private:
1341 /* The precision of the integer, which is a fixed property of the
1342 parent trailing_wide_ints. */
1343 unsigned int m_precision;
1344
1345 /* A pointer to the length field. */
1346 unsigned char *m_len;
1347
1348 /* A pointer to the HWI array. There are enough elements to hold all
1349 values of precision M_PRECISION. */
1350 HOST_WIDE_INTlong *m_val;
1351
1352public:
1353 trailing_wide_int_storage (unsigned int, unsigned char *, HOST_WIDE_INTlong *);
1354
1355 /* The standard generic_wide_int storage methods. */
1356 unsigned int get_len () const;
1357 unsigned int get_precision () const;
1358 const HOST_WIDE_INTlong *get_val () const;
1359 HOST_WIDE_INTlong *write_val ();
1360 void set_len (unsigned int, bool = false);
1361
1362 template <typename T>
1363 trailing_wide_int_storage &operator = (const T &);
1364};
1365
1366typedef generic_wide_int <trailing_wide_int_storage> trailing_wide_int;
1367
1368/* trailing_wide_int behaves like a wide_int. */
1369namespace wi
1370{
1371 template <>
1372 struct int_traits <trailing_wide_int_storage>
1373 : public int_traits <wide_int_storage> {};
1374}
1375
1376/* An array of N wide_int-like objects that can be put at the end of
1377 a variable-sized structure. Use extra_size to calculate how many
1378 bytes beyond the sizeof need to be allocated. Use set_precision
1379 to initialize the structure. */
1380template <int N>
1381struct GTY((user)) trailing_wide_ints
1382{
1383private:
1384 /* The shared precision of each number. */
1385 unsigned short m_precision;
1386
1387 /* The shared maximum length of each number. */
1388 unsigned char m_max_len;
1389
1390 /* The current length of each number.
1391 Avoid char array so the whole structure is not a typeless storage
1392 that will, in turn, turn off TBAA on gimple, trees and RTL. */
1393 struct {unsigned char len;} m_len[N];
1394
1395 /* The variable-length part of the structure, which always contains
1396 at least one HWI. Element I starts at index I * M_MAX_LEN. */
1397 HOST_WIDE_INTlong m_val[1];
1398
1399public:
1400 typedef WIDE_INT_REF_FOR (trailing_wide_int_storage)generic_wide_int <wide_int_ref_storage <wi::int_traits <
trailing_wide_int_storage>::is_sign_extended, wi::int_traits
<trailing_wide_int_storage>::host_dependent_precision>
>
const_reference;
1401
1402 void set_precision (unsigned int);
1403 unsigned int get_precision () const { return m_precision; }
1404 trailing_wide_int operator [] (unsigned int);
1405 const_reference operator [] (unsigned int) const;
1406 static size_t extra_size (unsigned int);
1407 size_t extra_size () const { return extra_size (m_precision); }
1408};
1409
1410inline trailing_wide_int_storage::
1411trailing_wide_int_storage (unsigned int precision, unsigned char *len,
1412 HOST_WIDE_INTlong *val)
1413 : m_precision (precision), m_len (len), m_val (val)
1414{
1415}
1416
1417inline unsigned int
1418trailing_wide_int_storage::get_len () const
1419{
1420 return *m_len;
1421}
1422
1423inline unsigned int
1424trailing_wide_int_storage::get_precision () const
1425{
1426 return m_precision;
1427}
1428
1429inline const HOST_WIDE_INTlong *
1430trailing_wide_int_storage::get_val () const
1431{
1432 return m_val;
1433}
1434
1435inline HOST_WIDE_INTlong *
1436trailing_wide_int_storage::write_val ()
1437{
1438 return m_val;
1439}
1440
1441inline void
1442trailing_wide_int_storage::set_len (unsigned int len, bool is_sign_extended)
1443{
1444 *m_len = len;
1445 if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT64 > m_precision)
1446 m_val[len - 1] = sext_hwi (m_val[len - 1],
1447 m_precision % HOST_BITS_PER_WIDE_INT64);
1448}
1449
1450template <typename T>
1451inline trailing_wide_int_storage &
1452trailing_wide_int_storage::operator = (const T &x)
1453{
1454 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, m_precision);
1455 wi::copy (*this, xi);
1456 return *this;
1457}
1458
1459/* Initialize the structure and record that all elements have precision
1460 PRECISION. */
1461template <int N>
1462inline void
1463trailing_wide_ints <N>::set_precision (unsigned int precision)
1464{
1465 m_precision = precision;
1466 m_max_len = ((precision + HOST_BITS_PER_WIDE_INT64 - 1)
1467 / HOST_BITS_PER_WIDE_INT64);
1468}
1469
1470/* Return a reference to element INDEX. */
1471template <int N>
1472inline trailing_wide_int
1473trailing_wide_ints <N>::operator [] (unsigned int index)
1474{
1475 return trailing_wide_int_storage (m_precision, &m_len[index].len,
1476 &m_val[index * m_max_len]);
1477}
1478
1479template <int N>
1480inline typename trailing_wide_ints <N>::const_reference
1481trailing_wide_ints <N>::operator [] (unsigned int index) const
1482{
1483 return wi::storage_ref (&m_val[index * m_max_len],
1484 m_len[index].len, m_precision);
1485}
1486
1487/* Return how many extra bytes need to be added to the end of the structure
1488 in order to handle N wide_ints of precision PRECISION. */
1489template <int N>
1490inline size_t
1491trailing_wide_ints <N>::extra_size (unsigned int precision)
1492{
1493 unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT64 - 1)
1494 / HOST_BITS_PER_WIDE_INT64);
1495 return (N * max_len - 1) * sizeof (HOST_WIDE_INTlong);
1496}
1497
1498/* This macro is used in structures that end with a trailing_wide_ints field
1499 called FIELD. It declares get_NAME() and set_NAME() methods to access
1500 element I of FIELD. */
1501#define TRAILING_WIDE_INT_ACCESSOR(NAME, FIELD, I)trailing_wide_int get_NAME () { return FIELD[I]; } template <
typename T> void set_NAME (const T &x) { FIELD[I] = x;
}
\
1502 trailing_wide_int get_##NAME () { return FIELD[I]; } \
1503 template <typename T> void set_##NAME (const T &x) { FIELD[I] = x; }
1504
1505namespace wi
1506{
1507 /* Implementation of int_traits for primitive integer types like "int". */
1508 template <typename T, bool signed_p>
1509 struct primitive_int_traits
1510 {
1511 static const enum precision_type precision_type = FLEXIBLE_PRECISION;
1512 static const bool host_dependent_precision = true;
1513 static const bool is_sign_extended = true;
1514 static unsigned int get_precision (T);
1515 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int, T);
1516 };
1517}
1518
1519template <typename T, bool signed_p>
1520inline unsigned int
1521wi::primitive_int_traits <T, signed_p>::get_precision (T)
1522{
1523 return sizeof (T) * CHAR_BIT8;
1524}
1525
1526template <typename T, bool signed_p>
1527inline wi::storage_ref
1528wi::primitive_int_traits <T, signed_p>::decompose (HOST_WIDE_INTlong *scratch,
1529 unsigned int precision, T x)
1530{
1531 scratch[0] = x;
1532 if (signed_p || scratch[0] >= 0 || precision <= HOST_BITS_PER_WIDE_INT64)
1533 return wi::storage_ref (scratch, 1, precision);
1534 scratch[1] = 0;
1535 return wi::storage_ref (scratch, 2, precision);
1536}
1537
1538/* Allow primitive C types to be used in wi:: routines. */
1539namespace wi
1540{
1541 template <>
1542 struct int_traits <unsigned char>
1543 : public primitive_int_traits <unsigned char, false> {};
1544
1545 template <>
1546 struct int_traits <unsigned short>
1547 : public primitive_int_traits <unsigned short, false> {};
1548
1549 template <>
1550 struct int_traits <int>
1551 : public primitive_int_traits <int, true> {};
1552
1553 template <>
1554 struct int_traits <unsigned int>
1555 : public primitive_int_traits <unsigned int, false> {};
1556
1557 template <>
1558 struct int_traits <long>
1559 : public primitive_int_traits <long, true> {};
1560
1561 template <>
1562 struct int_traits <unsigned long>
1563 : public primitive_int_traits <unsigned long, false> {};
1564
1565#if defined HAVE_LONG_LONG1
1566 template <>
1567 struct int_traits <long long>
1568 : public primitive_int_traits <long long, true> {};
1569
1570 template <>
1571 struct int_traits <unsigned long long>
1572 : public primitive_int_traits <unsigned long long, false> {};
1573#endif
1574}
1575
1576namespace wi
1577{
1578 /* Stores HWI-sized integer VAL, treating it as having signedness SGN
1579 and precision PRECISION. */
1580 class hwi_with_prec
1581 {
1582 public:
1583 hwi_with_prec () {}
1584 hwi_with_prec (HOST_WIDE_INTlong, unsigned int, signop);
1585 HOST_WIDE_INTlong val;
1586 unsigned int precision;
1587 signop sgn;
1588 };
1589
1590 hwi_with_prec shwi (HOST_WIDE_INTlong, unsigned int);
1591 hwi_with_prec uhwi (unsigned HOST_WIDE_INTlong, unsigned int);
1592
1593 hwi_with_prec minus_one (unsigned int);
1594 hwi_with_prec zero (unsigned int);
1595 hwi_with_prec one (unsigned int);
1596 hwi_with_prec two (unsigned int);
1597}
1598
1599inline wi::hwi_with_prec::hwi_with_prec (HOST_WIDE_INTlong v, unsigned int p,
1600 signop s)
1601 : precision (p), sgn (s)
1602{
1603 if (precision < HOST_BITS_PER_WIDE_INT64)
1604 val = sext_hwi (v, precision);
1605 else
1606 val = v;
1607}
1608
1609/* Return a signed integer that has value VAL and precision PRECISION. */
1610inline wi::hwi_with_prec
1611wi::shwi (HOST_WIDE_INTlong val, unsigned int precision)
1612{
1613 return hwi_with_prec (val, precision, SIGNED);
1614}
1615
1616/* Return an unsigned integer that has value VAL and precision PRECISION. */
1617inline wi::hwi_with_prec
1618wi::uhwi (unsigned HOST_WIDE_INTlong val, unsigned int precision)
1619{
1620 return hwi_with_prec (val, precision, UNSIGNED);
1621}
1622
1623/* Return a wide int of -1 with precision PRECISION. */
1624inline wi::hwi_with_prec
1625wi::minus_one (unsigned int precision)
1626{
1627 return wi::shwi (-1, precision);
1628}
1629
1630/* Return a wide int of 0 with precision PRECISION. */
1631inline wi::hwi_with_prec
1632wi::zero (unsigned int precision)
1633{
1634 return wi::shwi (0, precision);
1635}
1636
1637/* Return a wide int of 1 with precision PRECISION. */
1638inline wi::hwi_with_prec
1639wi::one (unsigned int precision)
1640{
1641 return wi::shwi (1, precision);
1642}
1643
1644/* Return a wide int of 2 with precision PRECISION. */
1645inline wi::hwi_with_prec
1646wi::two (unsigned int precision)
1647{
1648 return wi::shwi (2, precision);
1649}
1650
1651namespace wi
1652{
1653 /* ints_for<T>::zero (X) returns a zero that, when asssigned to a T,
1654 gives that T the same precision as X. */
1655 template<typename T, precision_type = int_traits<T>::precision_type>
1656 struct ints_for
1657 {
1658 static int zero (const T &) { return 0; }
1659 };
1660
1661 template<typename T>
1662 struct ints_for<T, VAR_PRECISION>
1663 {
1664 static hwi_with_prec zero (const T &);
1665 };
1666}
1667
1668template<typename T>
1669inline wi::hwi_with_prec
1670wi::ints_for<T, wi::VAR_PRECISION>::zero (const T &x)
1671{
1672 return wi::zero (wi::get_precision (x));
1673}
1674
1675namespace wi
1676{
1677 template <>
1678 struct int_traits <wi::hwi_with_prec>
1679 {
1680 static const enum precision_type precision_type = VAR_PRECISION;
1681 /* hwi_with_prec has an explicitly-given precision, rather than the
1682 precision of HOST_WIDE_INT. */
1683 static const bool host_dependent_precision = false;
1684 static const bool is_sign_extended = true;
1685 static unsigned int get_precision (const wi::hwi_with_prec &);
1686 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int,
1687 const wi::hwi_with_prec &);
1688 };
1689}
1690
1691inline unsigned int
1692wi::int_traits <wi::hwi_with_prec>::get_precision (const wi::hwi_with_prec &x)
1693{
1694 return x.precision;
1695}
1696
1697inline wi::storage_ref
1698wi::int_traits <wi::hwi_with_prec>::
1699decompose (HOST_WIDE_INTlong *scratch, unsigned int precision,
1700 const wi::hwi_with_prec &x)
1701{
1702 gcc_checking_assert (precision == x.precision)((void)(!(precision == x.precision) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 1702, __FUNCTION__), 0 : 0))
;
1703 scratch[0] = x.val;
1704 if (x.sgn == SIGNED || x.val >= 0 || precision <= HOST_BITS_PER_WIDE_INT64)
1705 return wi::storage_ref (scratch, 1, precision);
1706 scratch[1] = 0;
1707 return wi::storage_ref (scratch, 2, precision);
1708}
1709
1710/* Private functions for handling large cases out of line. They take
1711 individual length and array parameters because that is cheaper for
1712 the inline caller than constructing an object on the stack and
1713 passing a reference to it. (Although many callers use wide_int_refs,
1714 we generally want those to be removed by SRA.) */
1715namespace wi
1716{
1717 bool eq_p_large (const HOST_WIDE_INTlong *, unsigned int,
1718 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1719 bool lts_p_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1720 const HOST_WIDE_INTlong *, unsigned int);
1721 bool ltu_p_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1722 const HOST_WIDE_INTlong *, unsigned int);
1723 int cmps_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1724 const HOST_WIDE_INTlong *, unsigned int);
1725 int cmpu_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1726 const HOST_WIDE_INTlong *, unsigned int);
1727 unsigned int sext_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1728 unsigned int,
1729 unsigned int, unsigned int);
1730 unsigned int zext_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1731 unsigned int,
1732 unsigned int, unsigned int);
1733 unsigned int set_bit_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1734 unsigned int, unsigned int, unsigned int);
1735 unsigned int lshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1736 unsigned int, unsigned int, unsigned int);
1737 unsigned int lrshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1738 unsigned int, unsigned int, unsigned int,
1739 unsigned int);
1740 unsigned int arshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1741 unsigned int, unsigned int, unsigned int,
1742 unsigned int);
1743 unsigned int and_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1744 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1745 unsigned int and_not_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1746 unsigned int, const HOST_WIDE_INTlong *,
1747 unsigned int, unsigned int);
1748 unsigned int or_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1749 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1750 unsigned int or_not_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1751 unsigned int, const HOST_WIDE_INTlong *,
1752 unsigned int, unsigned int);
1753 unsigned int xor_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1754 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1755 unsigned int add_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1756 const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1757 signop, overflow_type *);
1758 unsigned int sub_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1759 const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1760 signop, overflow_type *);
1761 unsigned int mul_internal (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1762 unsigned int, const HOST_WIDE_INTlong *,
1763 unsigned int, unsigned int, signop,
1764 overflow_type *, bool);
1765 unsigned int divmod_internal (HOST_WIDE_INTlong *, unsigned int *,
1766 HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1767 unsigned int, unsigned int,
1768 const HOST_WIDE_INTlong *,
1769 unsigned int, unsigned int,
1770 signop, overflow_type *);
1771}
1772
1773/* Return the number of bits that integer X can hold. */
1774template <typename T>
1775inline unsigned int
1776wi::get_precision (const T &x)
1777{
1778 return wi::int_traits <T>::get_precision (x);
1779}
1780
1781/* Return the number of bits that the result of a binary operation can
1782 hold when the input operands are X and Y. */
1783template <typename T1, typename T2>
1784inline unsigned int
1785wi::get_binary_precision (const T1 &x, const T2 &y)
1786{
1787 return get_precision (wi::int_traits <WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type>::
1788 get_binary_result (x, y));
1789}
1790
1791/* Copy the contents of Y to X, but keeping X's current precision. */
1792template <typename T1, typename T2>
1793inline void
1794wi::copy (T1 &x, const T2 &y)
1795{
1796 HOST_WIDE_INTlong *xval = x.write_val ();
1797 const HOST_WIDE_INTlong *yval = y.get_val ();
1798 unsigned int len = y.get_len ();
1799 unsigned int i = 0;
1800 do
1801 xval[i] = yval[i];
1802 while (++i < len);
1803 x.set_len (len, y.is_sign_extended);
1804}
1805
1806/* Return true if X fits in a HOST_WIDE_INT with no loss of precision. */
1807template <typename T>
1808inline bool
1809wi::fits_shwi_p (const T &x)
1810{
1811 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1812 return xi.len == 1;
1813}
1814
1815/* Return true if X fits in an unsigned HOST_WIDE_INT with no loss of
1816 precision. */
1817template <typename T>
1818inline bool
1819wi::fits_uhwi_p (const T &x)
1820{
1821 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1822 if (xi.precision
17.1
Field 'precision' is <= HOST_BITS_PER_WIDE_INT
17.1
Field 'precision' is <= HOST_BITS_PER_WIDE_INT
17.1
Field 'precision' is <= HOST_BITS_PER_WIDE_INT
<= HOST_BITS_PER_WIDE_INT64
)
13
Assuming field 'precision' is <= HOST_BITS_PER_WIDE_INT
14
Taking true branch
18
Taking true branch
1823 return true;
15
Returning the value 1, which participates in a condition later
19
Returning the value 1, which participates in a condition later
1824 if (xi.len == 1)
1825 return xi.slow () >= 0;
1826 return xi.len == 2 && xi.uhigh () == 0;
1827}
1828
1829/* Return true if X is negative based on the interpretation of SGN.
1830 For UNSIGNED, this is always false. */
1831template <typename T>
1832inline bool
1833wi::neg_p (const T &x, signop sgn)
1834{
1835 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1836 if (sgn == UNSIGNED)
1837 return false;
1838 return xi.sign_mask () < 0;
1839}
1840
1841/* Return -1 if the top bit of X is set and 0 if the top bit is clear. */
1842template <typename T>
1843inline HOST_WIDE_INTlong
1844wi::sign_mask (const T &x)
1845{
1846 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1847 return xi.sign_mask ();
1848}
1849
1850/* Return true if X == Y. X and Y must be binary-compatible. */
1851template <typename T1, typename T2>
1852inline bool
1853wi::eq_p (const T1 &x, const T2 &y)
1854{
1855 unsigned int precision = get_binary_precision (x, y);
1856 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1857 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1858 if (xi.is_sign_extended && yi.is_sign_extended)
1859 {
1860 /* This case reduces to array equality. */
1861 if (xi.len != yi.len)
1862 return false;
1863 unsigned int i = 0;
1864 do
1865 if (xi.val[i] != yi.val[i])
1866 return false;
1867 while (++i != xi.len);
1868 return true;
1869 }
1870 if (__builtin_expect (yi.len == 1, true))
1871 {
1872 /* XI is only equal to YI if it too has a single HWI. */
1873 if (xi.len != 1)
1874 return false;
1875 /* Excess bits in xi.val[0] will be signs or zeros, so comparisons
1876 with 0 are simple. */
1877 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
1878 return xi.val[0] == 0;
1879 /* Otherwise flush out any excess bits first. */
1880 unsigned HOST_WIDE_INTlong diff = xi.val[0] ^ yi.val[0];
1881 int excess = HOST_BITS_PER_WIDE_INT64 - precision;
1882 if (excess > 0)
1883 diff <<= excess;
1884 return diff == 0;
1885 }
1886 return eq_p_large (xi.val, xi.len, yi.val, yi.len, precision);
1887}
1888
1889/* Return true if X != Y. X and Y must be binary-compatible. */
1890template <typename T1, typename T2>
1891inline bool
1892wi::ne_p (const T1 &x, const T2 &y)
1893{
1894 return !eq_p (x, y);
1895}
1896
1897/* Return true if X < Y when both are treated as signed values. */
1898template <typename T1, typename T2>
1899inline bool
1900wi::lts_p (const T1 &x, const T2 &y)
1901{
1902 unsigned int precision = get_binary_precision (x, y);
1903 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1904 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1905 /* We optimize x < y, where y is 64 or fewer bits. */
1906 if (wi::fits_shwi_p (yi))
1907 {
1908 /* Make lts_p (x, 0) as efficient as wi::neg_p (x). */
1909 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
1910 return neg_p (xi);
1911 /* If x fits directly into a shwi, we can compare directly. */
1912 if (wi::fits_shwi_p (xi))
1913 return xi.to_shwi () < yi.to_shwi ();
1914 /* If x doesn't fit and is negative, then it must be more
1915 negative than any value in y, and hence smaller than y. */
1916 if (neg_p (xi))
1917 return true;
1918 /* If x is positive, then it must be larger than any value in y,
1919 and hence greater than y. */
1920 return false;
1921 }
1922 /* Optimize the opposite case, if it can be detected at compile time. */
1923 if (STATIC_CONSTANT_P (xi.len == 1)(__builtin_constant_p (xi.len == 1) && (xi.len == 1)))
1924 /* If YI is negative it is lower than the least HWI.
1925 If YI is positive it is greater than the greatest HWI. */
1926 return !neg_p (yi);
1927 return lts_p_large (xi.val, xi.len, precision, yi.val, yi.len);
1928}
1929
1930/* Return true if X < Y when both are treated as unsigned values. */
1931template <typename T1, typename T2>
1932inline bool
1933wi::ltu_p (const T1 &x, const T2 &y)
1934{
1935 unsigned int precision = get_binary_precision (x, y);
1936 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1937 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1938 /* Optimize comparisons with constants. */
1939 if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)(__builtin_constant_p (yi.len == 1 && yi.val[0] >=
0) && (yi.len == 1 && yi.val[0] >= 0))
)
1940 return xi.len == 1 && xi.to_uhwi () < (unsigned HOST_WIDE_INTlong) yi.val[0];
1941 if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)(__builtin_constant_p (xi.len == 1 && xi.val[0] >=
0) && (xi.len == 1 && xi.val[0] >= 0))
)
1942 return yi.len != 1 || yi.to_uhwi () > (unsigned HOST_WIDE_INTlong) xi.val[0];
1943 /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended
1944 for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
1945 values does not change the result. */
1946 if (__builtin_expect (xi.len + yi.len == 2, true))
1947 {
1948 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
1949 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
1950 return xl < yl;
1951 }
1952 return ltu_p_large (xi.val, xi.len, precision, yi.val, yi.len);
1953}
1954
1955/* Return true if X < Y. Signedness of X and Y is indicated by SGN. */
1956template <typename T1, typename T2>
1957inline bool
1958wi::lt_p (const T1 &x, const T2 &y, signop sgn)
1959{
1960 if (sgn == SIGNED)
1961 return lts_p (x, y);
1962 else
1963 return ltu_p (x, y);
1964}
1965
1966/* Return true if X <= Y when both are treated as signed values. */
1967template <typename T1, typename T2>
1968inline bool
1969wi::les_p (const T1 &x, const T2 &y)
1970{
1971 return !lts_p (y, x);
1972}
1973
1974/* Return true if X <= Y when both are treated as unsigned values. */
1975template <typename T1, typename T2>
1976inline bool
1977wi::leu_p (const T1 &x, const T2 &y)
1978{
1979 return !ltu_p (y, x);
1980}
1981
1982/* Return true if X <= Y. Signedness of X and Y is indicated by SGN. */
1983template <typename T1, typename T2>
1984inline bool
1985wi::le_p (const T1 &x, const T2 &y, signop sgn)
1986{
1987 if (sgn == SIGNED)
1988 return les_p (x, y);
1989 else
1990 return leu_p (x, y);
1991}
1992
1993/* Return true if X > Y when both are treated as signed values. */
1994template <typename T1, typename T2>
1995inline bool
1996wi::gts_p (const T1 &x, const T2 &y)
1997{
1998 return lts_p (y, x);
1999}
2000
2001/* Return true if X > Y when both are treated as unsigned values. */
2002template <typename T1, typename T2>
2003inline bool
2004wi::gtu_p (const T1 &x, const T2 &y)
2005{
2006 return ltu_p (y, x);
2007}
2008
2009/* Return true if X > Y. Signedness of X and Y is indicated by SGN. */
2010template <typename T1, typename T2>
2011inline bool
2012wi::gt_p (const T1 &x, const T2 &y, signop sgn)
2013{
2014 if (sgn == SIGNED)
2015 return gts_p (x, y);
2016 else
2017 return gtu_p (x, y);
2018}
2019
2020/* Return true if X >= Y when both are treated as signed values. */
2021template <typename T1, typename T2>
2022inline bool
2023wi::ges_p (const T1 &x, const T2 &y)
2024{
2025 return !lts_p (x, y);
2026}
2027
2028/* Return true if X >= Y when both are treated as unsigned values. */
2029template <typename T1, typename T2>
2030inline bool
2031wi::geu_p (const T1 &x, const T2 &y)
2032{
2033 return !ltu_p (x, y);
2034}
2035
2036/* Return true if X >= Y. Signedness of X and Y is indicated by SGN. */
2037template <typename T1, typename T2>
2038inline bool
2039wi::ge_p (const T1 &x, const T2 &y, signop sgn)
2040{
2041 if (sgn == SIGNED)
2042 return ges_p (x, y);
2043 else
2044 return geu_p (x, y);
2045}
2046
2047/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y
2048 as signed values. */
2049template <typename T1, typename T2>
2050inline int
2051wi::cmps (const T1 &x, const T2 &y)
2052{
2053 unsigned int precision = get_binary_precision (x, y);
2054 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2055 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2056 if (wi::fits_shwi_p (yi))
2057 {
2058 /* Special case for comparisons with 0. */
2059 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
2060 return neg_p (xi) ? -1 : !(xi.len == 1 && xi.val[0] == 0);
2061 /* If x fits into a signed HWI, we can compare directly. */
2062 if (wi::fits_shwi_p (xi))
2063 {
2064 HOST_WIDE_INTlong xl = xi.to_shwi ();
2065 HOST_WIDE_INTlong yl = yi.to_shwi ();
2066 return xl < yl ? -1 : xl > yl;
2067 }
2068 /* If x doesn't fit and is negative, then it must be more
2069 negative than any signed HWI, and hence smaller than y. */
2070 if (neg_p (xi))
2071 return -1;
2072 /* If x is positive, then it must be larger than any signed HWI,
2073 and hence greater than y. */
2074 return 1;
2075 }
2076 /* Optimize the opposite case, if it can be detected at compile time. */
2077 if (STATIC_CONSTANT_P (xi.len == 1)(__builtin_constant_p (xi.len == 1) && (xi.len == 1)))
2078 /* If YI is negative it is lower than the least HWI.
2079 If YI is positive it is greater than the greatest HWI. */
2080 return neg_p (yi) ? 1 : -1;
2081 return cmps_large (xi.val, xi.len, precision, yi.val, yi.len);
2082}
2083
2084/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y
2085 as unsigned values. */
2086template <typename T1, typename T2>
2087inline int
2088wi::cmpu (const T1 &x, const T2 &y)
2089{
2090 unsigned int precision = get_binary_precision (x, y);
2091 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2092 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2093 /* Optimize comparisons with constants. */
2094 if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)(__builtin_constant_p (yi.len == 1 && yi.val[0] >=
0) && (yi.len == 1 && yi.val[0] >= 0))
)
2095 {
2096 /* If XI doesn't fit in a HWI then it must be larger than YI. */
2097 if (xi.len != 1)
2098 return 1;
2099 /* Otherwise compare directly. */
2100 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
2101 unsigned HOST_WIDE_INTlong yl = yi.val[0];
2102 return xl < yl ? -1 : xl > yl;
2103 }
2104 if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)(__builtin_constant_p (xi.len == 1 && xi.val[0] >=
0) && (xi.len == 1 && xi.val[0] >= 0))
)
2105 {
2106 /* If YI doesn't fit in a HWI then it must be larger than XI. */
2107 if (yi.len != 1)
2108 return -1;
2109 /* Otherwise compare directly. */
2110 unsigned HOST_WIDE_INTlong xl = xi.val[0];
2111 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
2112 return xl < yl ? -1 : xl > yl;
2113 }
2114 /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended
2115 for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
2116 values does not change the result. */
2117 if (__builtin_expect (xi.len + yi.len == 2, true))
2118 {
2119 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
2120 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
2121 return xl < yl ? -1 : xl > yl;
2122 }
2123 return cmpu_large (xi.val, xi.len, precision, yi.val, yi.len);
2124}
2125
2126/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Signedness of
2127 X and Y indicated by SGN. */
2128template <typename T1, typename T2>
2129inline int
2130wi::cmp (const T1 &x, const T2 &y, signop sgn)
2131{
2132 if (sgn == SIGNED)
2133 return cmps (x, y);
2134 else
2135 return cmpu (x, y);
2136}
2137
2138/* Return ~x. */
2139template <typename T>
2140inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2141wi::bit_not (const T &x)
2142{
2143 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2144 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, get_precision (result));
2145 for (unsigned int i = 0; i < xi.len; ++i)
2146 val[i] = ~xi.val[i];
2147 result.set_len (xi.len);
2148 return result;
2149}
2150
2151/* Return -x. */
2152template <typename T>
2153inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2154wi::neg (const T &x)
2155{
2156 return sub (0, x);
2157}
2158
2159/* Return -x. Indicate in *OVERFLOW if performing the negation would
2160 cause an overflow. */
2161template <typename T>
2162inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2163wi::neg (const T &x, overflow_type *overflow)
2164{
2165 *overflow = only_sign_bit_p (x) ? OVF_OVERFLOW : OVF_NONE;
2166 return sub (0, x);
2167}
2168
2169/* Return the absolute value of x. */
2170template <typename T>
2171inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2172wi::abs (const T &x)
2173{
2174 return neg_p (x) ? neg (x) : WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type (x);
2175}
2176
2177/* Return the result of sign-extending the low OFFSET bits of X. */
2178template <typename T>
2179inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2180wi::sext (const T &x, unsigned int offset)
2181{
2182 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2183 unsigned int precision = get_precision (result);
2184 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2185
2186 if (offset <= HOST_BITS_PER_WIDE_INT64)
2187 {
2188 val[0] = sext_hwi (xi.ulow (), offset);
2189 result.set_len (1, true);
2190 }
2191 else
2192 result.set_len (sext_large (val, xi.val, xi.len, precision, offset));
2193 return result;
2194}
2195
2196/* Return the result of zero-extending the low OFFSET bits of X. */
2197template <typename T>
2198inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2199wi::zext (const T &x, unsigned int offset)
2200{
2201 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2202 unsigned int precision = get_precision (result);
2203 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2204
2205 /* This is not just an optimization, it is actually required to
2206 maintain canonization. */
2207 if (offset >= precision)
2208 {
2209 wi::copy (result, xi);
2210 return result;
2211 }
2212
2213 /* In these cases we know that at least the top bit will be clear,
2214 so no sign extension is necessary. */
2215 if (offset < HOST_BITS_PER_WIDE_INT64)
2216 {
2217 val[0] = zext_hwi (xi.ulow (), offset);
2218 result.set_len (1, true);
2219 }
2220 else
2221 result.set_len (zext_large (val, xi.val, xi.len, precision, offset), true);
2222 return result;
2223}
2224
2225/* Return the result of extending the low OFFSET bits of X according to
2226 signedness SGN. */
2227template <typename T>
2228inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2229wi::ext (const T &x, unsigned int offset, signop sgn)
2230{
2231 return sgn == SIGNED ? sext (x, offset) : zext (x, offset);
2232}
2233
2234/* Return an integer that represents X | (1 << bit). */
2235template <typename T>
2236inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2237wi::set_bit (const T &x, unsigned int bit)
2238{
2239 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2240 unsigned int precision = get_precision (result);
2241 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2242 if (precision <= HOST_BITS_PER_WIDE_INT64)
2243 {
2244 val[0] = xi.ulow () | (HOST_WIDE_INT_1U1UL << bit);
2245 result.set_len (1);
2246 }
2247 else
2248 result.set_len (set_bit_large (val, xi.val, xi.len, precision, bit));
2249 return result;
2250}
2251
2252/* Return the mininum of X and Y, treating them both as having
2253 signedness SGN. */
2254template <typename T1, typename T2>
2255inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2256wi::min (const T1 &x, const T2 &y, signop sgn)
2257{
2258 WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val __attribute__
((__unused__)) = result.write_val ()
;
2259 unsigned int precision = get_precision (result);
2260 if (wi::le_p (x, y, sgn))
2261 wi::copy (result, WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
(x, precision));
2262 else
2263 wi::copy (result, WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
(y, precision));
2264 return result;
2265}
2266
2267/* Return the minimum of X and Y, treating both as signed values. */
2268template <typename T1, typename T2>
2269inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2270wi::smin (const T1 &x, const T2 &y)
2271{
2272 return wi::min (x, y, SIGNED);
2273}
2274
2275/* Return the minimum of X and Y, treating both as unsigned values. */
2276template <typename T1, typename T2>
2277inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2278wi::umin (const T1 &x, const T2 &y)
2279{
2280 return wi::min (x, y, UNSIGNED);
2281}
2282
2283/* Return the maxinum of X and Y, treating them both as having
2284 signedness SGN. */
2285template <typename T1, typename T2>
2286inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2287wi::max (const T1 &x, const T2 &y, signop sgn)
2288{
2289 WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val __attribute__
((__unused__)) = result.write_val ()
;
2290 unsigned int precision = get_precision (result);
2291 if (wi::ge_p (x, y, sgn))
2292 wi::copy (result, WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
(x, precision));
2293 else
2294 wi::copy (result, WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
(y, precision));
2295 return result;
2296}
2297
2298/* Return the maximum of X and Y, treating both as signed values. */
2299template <typename T1, typename T2>
2300inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2301wi::smax (const T1 &x, const T2 &y)
2302{
2303 return wi::max (x, y, SIGNED);
2304}
2305
2306/* Return the maximum of X and Y, treating both as unsigned values. */
2307template <typename T1, typename T2>
2308inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2309wi::umax (const T1 &x, const T2 &y)
2310{
2311 return wi::max (x, y, UNSIGNED);
2312}
2313
2314/* Return X & Y. */
2315template <typename T1, typename T2>
2316inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2317wi::bit_and (const T1 &x, const T2 &y)
2318{
2319 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2320 unsigned int precision = get_precision (result);
2321 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2322 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2323 bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
2324 if (__builtin_expect (xi.len + yi.len == 2, true))
2325 {
2326 val[0] = xi.ulow () & yi.ulow ();
2327 result.set_len (1, is_sign_extended);
2328 }
2329 else
2330 result.set_len (and_large (val, xi.val, xi.len, yi.val, yi.len,
2331 precision), is_sign_extended);
2332 return result;
2333}
2334
2335/* Return X & ~Y. */
2336template <typename T1, typename T2>
2337inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2338wi::bit_and_not (const T1 &x, const T2 &y)
2339{
2340 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2341 unsigned int precision = get_precision (result);
2342 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2343 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2344 bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
2345 if (__builtin_expect (xi.len + yi.len == 2, true))
2346 {
2347 val[0] = xi.ulow () & ~yi.ulow ();
2348 result.set_len (1, is_sign_extended);
2349 }
2350 else
2351 result.set_len (and_not_large (val, xi.val, xi.len, yi.val, yi.len,
2352 precision), is_sign_extended);
2353 return result;
2354}
2355
2356/* Return X | Y. */
2357template <typename T1, typename T2>
2358inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2359wi::bit_or (const T1 &x, const T2 &y)
2360{
2361 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2362 unsigned int precision = get_precision (result);
2363 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2364 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2365 bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
2366 if (__builtin_expect (xi.len + yi.len == 2, true))
2367 {
2368 val[0] = xi.ulow () | yi.ulow ();
2369 result.set_len (1, is_sign_extended);
2370 }
2371 else
2372 result.set_len (or_large (val, xi.val, xi.len,
2373 yi.val, yi.len, precision), is_sign_extended);
2374 return result;
2375}
2376
2377/* Return X | ~Y. */
2378template <typename T1, typename T2>
2379inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2380wi::bit_or_not (const T1 &x, const T2 &y)
2381{
2382 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2383 unsigned int precision = get_precision (result);
2384 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2385 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2386 bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
2387 if (__builtin_expect (xi.len + yi.len == 2, true))
2388 {
2389 val[0] = xi.ulow () | ~yi.ulow ();
2390 result.set_len (1, is_sign_extended);
2391 }
2392 else
2393 result.set_len (or_not_large (val, xi.val, xi.len, yi.val, yi.len,
2394 precision), is_sign_extended);
2395 return result;
2396}
2397
2398/* Return X ^ Y. */
2399template <typename T1, typename T2>
2400inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2401wi::bit_xor (const T1 &x, const T2 &y)
2402{
2403 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2404 unsigned int precision = get_precision (result);
2405 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2406 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2407 bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
2408 if (__builtin_expect (xi.len + yi.len == 2, true))
2409 {
2410 val[0] = xi.ulow () ^ yi.ulow ();
2411 result.set_len (1, is_sign_extended);
2412 }
2413 else
2414 result.set_len (xor_large (val, xi.val, xi.len,
2415 yi.val, yi.len, precision), is_sign_extended);
2416 return result;
2417}
2418
2419/* Return X + Y. */
2420template <typename T1, typename T2>
2421inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2422wi::add (const T1 &x, const T2 &y)
2423{
2424 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2425 unsigned int precision = get_precision (result);
2426 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2427 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2428 if (precision <= HOST_BITS_PER_WIDE_INT64)
2429 {
2430 val[0] = xi.ulow () + yi.ulow ();
2431 result.set_len (1);
2432 }
2433 /* If the precision is known at compile time to be greater than
2434 HOST_BITS_PER_WIDE_INT, we can optimize the single-HWI case
2435 knowing that (a) all bits in those HWIs are significant and
2436 (b) the result has room for at least two HWIs. This provides
2437 a fast path for things like offset_int and widest_int.
2438
2439 The STATIC_CONSTANT_P test prevents this path from being
2440 used for wide_ints. wide_ints with precisions greater than
2441 HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
2442 point handling them inline. */
2443 else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)(__builtin_constant_p (precision > 64) && (precision
> 64))
2444 && __builtin_expect (xi.len + yi.len == 2, true))
2445 {
2446 unsigned HOST_WIDE_INTlong xl = xi.ulow ();
2447 unsigned HOST_WIDE_INTlong yl = yi.ulow ();
2448 unsigned HOST_WIDE_INTlong resultl = xl + yl;
2449 val[0] = resultl;
2450 val[1] = (HOST_WIDE_INTlong) resultl < 0 ? 0 : -1;
2451 result.set_len (1 + (((resultl ^ xl) & (resultl ^ yl))
2452 >> (HOST_BITS_PER_WIDE_INT64 - 1)));
2453 }
2454 else
2455 result.set_len (add_large (val, xi.val, xi.len,
2456 yi.val, yi.len, precision,
2457 UNSIGNED, 0));
2458 return result;
2459}
2460
2461/* Return X + Y. Treat X and Y as having the signednes given by SGN
2462 and indicate in *OVERFLOW whether the operation overflowed. */
2463template <typename T1, typename T2>
2464inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2465wi::add (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2466{
2467 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2468 unsigned int precision = get_precision (result);
2469 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2470 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2471 if (precision <= HOST_BITS_PER_WIDE_INT64)
2472 {
2473 unsigned HOST_WIDE_INTlong xl = xi.ulow ();
2474 unsigned HOST_WIDE_INTlong yl = yi.ulow ();
2475 unsigned HOST_WIDE_INTlong resultl = xl + yl;
2476 if (sgn == SIGNED)
2477 {
2478 if ((((resultl ^ xl) & (resultl ^ yl))
2479 >> (precision - 1)) & 1)
2480 {
2481 if (xl > resultl)
2482 *overflow = OVF_UNDERFLOW;
2483 else if (xl < resultl)
2484 *overflow = OVF_OVERFLOW;
2485 else
2486 *overflow = OVF_NONE;
2487 }
2488 else
2489 *overflow = OVF_NONE;
2490 }
2491 else
2492 *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT64 - precision))
2493 < (xl << (HOST_BITS_PER_WIDE_INT64 - precision)))
2494 ? OVF_OVERFLOW : OVF_NONE;
2495 val[0] = resultl;
2496 result.set_len (1);
2497 }
2498 else
2499 result.set_len (add_large (val, xi.val, xi.len,
2500 yi.val, yi.len, precision,
2501 sgn, overflow));
2502 return result;
2503}
2504
2505/* Return X - Y. */
2506template <typename T1, typename T2>
2507inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2508wi::sub (const T1 &x, const T2 &y)
2509{
2510 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2511 unsigned int precision = get_precision (result);
2512 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2513 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2514 if (precision <= HOST_BITS_PER_WIDE_INT64)
2515 {
2516 val[0] = xi.ulow () - yi.ulow ();
2517 result.set_len (1);
2518 }
2519 /* If the precision is known at compile time to be greater than
2520 HOST_BITS_PER_WIDE_INT, we can optimize the single-HWI case
2521 knowing that (a) all bits in those HWIs are significant and
2522 (b) the result has room for at least two HWIs. This provides
2523 a fast path for things like offset_int and widest_int.
2524
2525 The STATIC_CONSTANT_P test prevents this path from being
2526 used for wide_ints. wide_ints with precisions greater than
2527 HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
2528 point handling them inline. */
2529 else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)(__builtin_constant_p (precision > 64) && (precision
> 64))
2530 && __builtin_expect (xi.len + yi.len == 2, true))
2531 {
2532 unsigned HOST_WIDE_INTlong xl = xi.ulow ();
2533 unsigned HOST_WIDE_INTlong yl = yi.ulow ();
2534 unsigned HOST_WIDE_INTlong resultl = xl - yl;
2535 val[0] = resultl;
2536 val[1] = (HOST_WIDE_INTlong) resultl < 0 ? 0 : -1;
2537 result.set_len (1 + (((resultl ^ xl) & (xl ^ yl))
2538 >> (HOST_BITS_PER_WIDE_INT64 - 1)));
2539 }
2540 else
2541 result.set_len (sub_large (val, xi.val, xi.len,
2542 yi.val, yi.len, precision,
2543 UNSIGNED, 0));
2544 return result;
2545}
2546
2547/* Return X - Y. Treat X and Y as having the signednes given by SGN
2548 and indicate in *OVERFLOW whether the operation overflowed. */
2549template <typename T1, typename T2>
2550inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2551wi::sub (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2552{
2553 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2554 unsigned int precision = get_precision (result);
2555 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2556 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2557 if (precision <= HOST_BITS_PER_WIDE_INT64)
2558 {
2559 unsigned HOST_WIDE_INTlong xl = xi.ulow ();
2560 unsigned HOST_WIDE_INTlong yl = yi.ulow ();
2561 unsigned HOST_WIDE_INTlong resultl = xl - yl;
2562 if (sgn == SIGNED)
2563 {
2564 if ((((xl ^ yl) & (resultl ^ xl)) >> (precision - 1)) & 1)
2565 {
2566 if (xl > yl)
2567 *overflow = OVF_UNDERFLOW;
2568 else if (xl < yl)
2569 *overflow = OVF_OVERFLOW;
2570 else
2571 *overflow = OVF_NONE;
2572 }
2573 else
2574 *overflow = OVF_NONE;
2575 }
2576 else
2577 *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT64 - precision))
2578 > (xl << (HOST_BITS_PER_WIDE_INT64 - precision)))
2579 ? OVF_UNDERFLOW : OVF_NONE;
2580 val[0] = resultl;
2581 result.set_len (1);
2582 }
2583 else
2584 result.set_len (sub_large (val, xi.val, xi.len,
2585 yi.val, yi.len, precision,
2586 sgn, overflow));
2587 return result;
2588}
2589
2590/* Return X * Y. */
2591template <typename T1, typename T2>
2592inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2593wi::mul (const T1 &x, const T2 &y)
2594{
2595 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2596 unsigned int precision = get_precision (result);
2597 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2598 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2599 if (precision <= HOST_BITS_PER_WIDE_INT64)
2600 {
2601 val[0] = xi.ulow () * yi.ulow ();
2602 result.set_len (1);
2603 }
2604 else
2605 result.set_len (mul_internal (val, xi.val, xi.len, yi.val, yi.len,
2606 precision, UNSIGNED, 0, false));
2607 return result;
2608}
2609
2610/* Return X * Y. Treat X and Y as having the signednes given by SGN
2611 and indicate in *OVERFLOW whether the operation overflowed. */
2612template <typename T1, typename T2>
2613inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2614wi::mul (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2615{
2616 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2617 unsigned int precision = get_precision (result);
2618 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2619 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2620 result.set_len (mul_internal (val, xi.val, xi.len,
2621 yi.val, yi.len, precision,
2622 sgn, overflow, false));
2623 return result;
2624}
2625
2626/* Return X * Y, treating both X and Y as signed values. Indicate in
2627 *OVERFLOW whether the operation overflowed. */
2628template <typename T1, typename T2>
2629inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2630wi::smul (const T1 &x, const T2 &y, overflow_type *overflow)
2631{
2632 return mul (x, y, SIGNED, overflow);
2633}
2634
2635/* Return X * Y, treating both X and Y as unsigned values. Indicate in
2636 *OVERFLOW if the result overflows. */
2637template <typename T1, typename T2>
2638inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2639wi::umul (const T1 &x, const T2 &y, overflow_type *overflow)
2640{
2641 return mul (x, y, UNSIGNED, overflow);
2642}
2643
2644/* Perform a widening multiplication of X and Y, extending the values
2645 according to SGN, and return the high part of the result. */
2646template <typename T1, typename T2>
2647inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2648wi::mul_high (const T1 &x, const T2 &y, signop sgn)
2649{
2650 WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val = result
.write_val ()
;
2651 unsigned int precision = get_precision (result);
2652 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2653 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2654 result.set_len (mul_internal (val, xi.val, xi.len,
2655 yi.val, yi.len, precision,
2656 sgn, 0, true));
2657 return result;
2658}
2659
2660/* Return X / Y, rouding towards 0. Treat X and Y as having the
2661 signedness given by SGN. Indicate in *OVERFLOW if the result
2662 overflows. */
2663template <typename T1, typename T2>
2664inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2665wi::div_trunc (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2666{
2667 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2668 unsigned int precision = get_precision (quotient);
2669 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2670 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2671
2672 quotient.set_len (divmod_internal (quotient_val, 0, 0, xi.val, xi.len,
2673 precision,
2674 yi.val, yi.len, yi.precision,
2675 sgn, overflow));
2676 return quotient;
2677}
2678
2679/* Return X / Y, rouding towards 0. Treat X and Y as signed values. */
2680template <typename T1, typename T2>
2681inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2682wi::sdiv_trunc (const T1 &x, const T2 &y)
2683{
2684 return div_trunc (x, y, SIGNED);
2685}
2686
2687/* Return X / Y, rouding towards 0. Treat X and Y as unsigned values. */
2688template <typename T1, typename T2>
2689inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2690wi::udiv_trunc (const T1 &x, const T2 &y)
2691{
2692 return div_trunc (x, y, UNSIGNED);
2693}
2694
2695/* Return X / Y, rouding towards -inf. Treat X and Y as having the
2696 signedness given by SGN. Indicate in *OVERFLOW if the result
2697 overflows. */
2698template <typename T1, typename T2>
2699inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2700wi::div_floor (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2701{
2702 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2703 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;
2704 unsigned int precision = get_precision (quotient);
2705 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2706 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2707
2708 unsigned int remainder_len;
2709 quotient.set_len (divmod_internal (quotient_val,
2710 &remainder_len, remainder_val,
2711 xi.val, xi.len, precision,
2712 yi.val, yi.len, yi.precision, sgn,
2713 overflow));
2714 remainder.set_len (remainder_len);
2715 if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn) && remainder != 0)
2716 return quotient - 1;
2717 return quotient;
2718}
2719
2720/* Return X / Y, rouding towards -inf. Treat X and Y as signed values. */
2721template <typename T1, typename T2>
2722inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2723wi::sdiv_floor (const T1 &x, const T2 &y)
2724{
2725 return div_floor (x, y, SIGNED);
2726}
2727
2728/* Return X / Y, rouding towards -inf. Treat X and Y as unsigned values. */
2729/* ??? Why do we have both this and udiv_trunc. Aren't they the same? */
2730template <typename T1, typename T2>
2731inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2732wi::udiv_floor (const T1 &x, const T2 &y)
2733{
2734 return div_floor (x, y, UNSIGNED);
2735}
2736
2737/* Return X / Y, rouding towards +inf. Treat X and Y as having the
2738 signedness given by SGN. Indicate in *OVERFLOW if the result
2739 overflows. */
2740template <typename T1, typename T2>
2741inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2742wi::div_ceil (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2743{
2744 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2745 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;
2746 unsigned int precision = get_precision (quotient);
2747 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2748 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2749
2750 unsigned int remainder_len;
2751 quotient.set_len (divmod_internal (quotient_val,
2752 &remainder_len, remainder_val,
2753 xi.val, xi.len, precision,
2754 yi.val, yi.len, yi.precision, sgn,
2755 overflow));
2756 remainder.set_len (remainder_len);
2757 if (wi::neg_p (x, sgn) == wi::neg_p (y, sgn) && remainder != 0)
2758 return quotient + 1;
2759 return quotient;
2760}
2761
2762/* Return X / Y, rouding towards +inf. Treat X and Y as unsigned values. */
2763template <typename T1, typename T2>
2764inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2765wi::udiv_ceil (const T1 &x, const T2 &y)
2766{
2767 return div_ceil (x, y, UNSIGNED);
2768}
2769
2770/* Return X / Y, rouding towards nearest with ties away from zero.
2771 Treat X and Y as having the signedness given by SGN. Indicate
2772 in *OVERFLOW if the result overflows. */
2773template <typename T1, typename T2>
2774inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2775wi::div_round (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2776{
2777 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2778 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;
2779 unsigned int precision = get_precision (quotient);
2780 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2781 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2782
2783 unsigned int remainder_len;
2784 quotient.set_len (divmod_internal (quotient_val,
2785 &remainder_len, remainder_val,
2786 xi.val, xi.len, precision,
2787 yi.val, yi.len, yi.precision, sgn,
2788 overflow));
2789 remainder.set_len (remainder_len);
2790
2791 if (remainder != 0)
2792 {
2793 if (sgn == SIGNED)
2794 {
2795 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type abs_remainder = wi::abs (remainder);
2796 if (wi::geu_p (abs_remainder, wi::sub (wi::abs (y), abs_remainder)))
2797 {
2798 if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn))
2799 return quotient - 1;
2800 else
2801 return quotient + 1;
2802 }
2803 }
2804 else
2805 {
2806 if (wi::geu_p (remainder, wi::sub (y, remainder)))
2807 return quotient + 1;
2808 }
2809 }
2810 return quotient;
2811}
2812
2813/* Return X / Y, rouding towards 0. Treat X and Y as having the
2814 signedness given by SGN. Store the remainder in *REMAINDER_PTR. */
2815template <typename T1, typename T2>
2816inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2817wi::divmod_trunc (const T1 &x, const T2 &y, signop sgn,
2818 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type *remainder_ptr)
2819{
2820 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2821 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;
2822 unsigned int precision = get_precision (quotient);
2823 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2824 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2825
2826 unsigned int remainder_len;
2827 quotient.set_len (divmod_internal (quotient_val,
2828 &remainder_len, remainder_val,
2829 xi.val, xi.len, precision,
2830 yi.val, yi.len, yi.precision, sgn, 0));
2831 remainder.set_len (remainder_len);
2832
2833 *remainder_ptr = remainder;
2834 return quotient;
2835}
2836
2837/* Compute the greatest common divisor of two numbers A and B using
2838 Euclid's algorithm. */
2839template <typename T1, typename T2>
2840inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2841wi::gcd (const T1 &a, const T2 &b, signop sgn)
2842{
2843 T1 x, y, z;
2844
2845 x = wi::abs (a);
2846 y = wi::abs (b);
2847
2848 while (gt_p (x, 0, sgn))
2
Loop condition is true. Entering loop body
2849 {
2850 z = mod_trunc (y, x, sgn);
3
Calling 'mod_trunc<generic_wide_int<wide_int_storage>, generic_wide_int<wide_int_storage>>'
2851 y = x;
2852 x = z;
2853 }
2854
2855 return y;
2856}
2857
2858/* Compute X / Y, rouding towards 0, and return the remainder.
2859 Treat X and Y as having the signedness given by SGN. Indicate
2860 in *OVERFLOW if the division overflows. */
2861template <typename T1, typename T2>
2862inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2863wi::mod_trunc (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2864{
2865 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;
2866 unsigned int precision = get_precision (remainder);
2867 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2868 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y);
2869
2870 unsigned int remainder_len;
2871 divmod_internal (0, &remainder_len, remainder_val,
4
Calling 'divmod_internal'
2872 xi.val, xi.len, precision,
2873 yi.val, yi.len, yi.precision, sgn, overflow);
2874 remainder.set_len (remainder_len);
2875
2876 return remainder;
2877}
2878
2879/* Compute X / Y, rouding towards 0, and return the remainder.
2880 Treat X and Y as signed values. */
2881template <typename T1, typename T2>
2882inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2883wi::smod_trunc (const T1 &x, const T2 &y)
2884{
2885 return mod_trunc (x, y, SIGNED);
2886}
2887
2888/* Compute X / Y, rouding towards 0, and return the remainder.
2889 Treat X and Y as unsigned values. */
2890template <typename T1, typename T2>
2891inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2892wi::umod_trunc (const T1 &x, const T2 &y)
2893{
2894 return mod_trunc (x, y, UNSIGNED);
2895}
2896
2897/* Compute X / Y, rouding towards -inf, and return the remainder.
2898 Treat X and Y as having the signedness given by SGN. Indicate
2899 in *OVERFLOW if the division overflows. */
2900template <typename T1, typename T2>
2901inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2902wi::mod_floor (const T1 &x, const T2 &y, signop sgn, overflow_type *overflow)
2903{
2904 WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type quotient
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *quotient_val
= quotient.write_val ()
;
2905 WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type remainder
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *remainder_val
= remainder.write_val ()
;