1169689Skan/* Operations with long integers.
2169689Skan   Copyright (C) 2006 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify it
7169689Skanunder the terms of the GNU General Public License as published by the
8169689SkanFree Software Foundation; either version 2, or (at your option) any
9169689Skanlater version.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT
12169689SkanANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14169689Skanfor more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19169689Skan02110-1301, USA.  */
20169689Skan
21169689Skan#include "config.h"
22169689Skan#include "system.h"
23169689Skan#include "coretypes.h"
24169689Skan#include "tm.h"
25169689Skan#include "tree.h"
26169689Skan
27169689Skan/* Returns mask for PREC bits.  */
28169689Skan
29169689Skanstatic inline double_int
30169689Skandouble_int_mask (unsigned prec)
31169689Skan{
32169689Skan  unsigned HOST_WIDE_INT m;
33169689Skan  double_int mask;
34169689Skan
35169689Skan  if (prec > HOST_BITS_PER_WIDE_INT)
36169689Skan    {
37169689Skan      prec -= HOST_BITS_PER_WIDE_INT;
38169689Skan      m = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
39169689Skan      mask.high = (HOST_WIDE_INT) m;
40169689Skan      mask.low = ALL_ONES;
41169689Skan    }
42169689Skan  else
43169689Skan    {
44169689Skan      mask.high = 0;
45169689Skan      mask.low = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
46169689Skan    }
47169689Skan
48169689Skan  return mask;
49169689Skan}
50169689Skan
51169689Skan/* Clears the bits of CST over the precision PREC.  If UNS is false, the bits
52169689Skan   outside of the precision are set to the sign bit (i.e., the PREC-th one),
53169689Skan   otherwise they are set to zero.
54169689Skan
55169689Skan   This corresponds to returning the value represented by PREC lowermost bits
56169689Skan   of CST, with the given signedness.  */
57169689Skan
58169689Skandouble_int
59169689Skandouble_int_ext (double_int cst, unsigned prec, bool uns)
60169689Skan{
61169689Skan  if (uns)
62169689Skan    return double_int_zext (cst, prec);
63169689Skan  else
64169689Skan    return double_int_sext (cst, prec);
65169689Skan}
66169689Skan
67169689Skan/* The same as double_int_ext with UNS = true.  */
68169689Skan
69169689Skandouble_int
70169689Skandouble_int_zext (double_int cst, unsigned prec)
71169689Skan{
72169689Skan  double_int mask = double_int_mask (prec);
73169689Skan  double_int r;
74169689Skan
75169689Skan  r.low = cst.low & mask.low;
76169689Skan  r.high = cst.high & mask.high;
77169689Skan
78169689Skan  return r;
79169689Skan}
80169689Skan
81169689Skan/* The same as double_int_ext with UNS = false.  */
82169689Skan
83169689Skandouble_int
84169689Skandouble_int_sext (double_int cst, unsigned prec)
85169689Skan{
86169689Skan  double_int mask = double_int_mask (prec);
87169689Skan  double_int r;
88169689Skan  unsigned HOST_WIDE_INT snum;
89169689Skan
90169689Skan  if (prec <= HOST_BITS_PER_WIDE_INT)
91169689Skan    snum = cst.low;
92169689Skan  else
93169689Skan    {
94169689Skan      prec -= HOST_BITS_PER_WIDE_INT;
95169689Skan      snum = (unsigned HOST_WIDE_INT) cst.high;
96169689Skan    }
97169689Skan  if (((snum >> (prec - 1)) & 1) == 1)
98169689Skan    {
99169689Skan      r.low = cst.low | ~mask.low;
100169689Skan      r.high = cst.high | ~mask.high;
101169689Skan    }
102169689Skan  else
103169689Skan    {
104169689Skan      r.low = cst.low & mask.low;
105169689Skan      r.high = cst.high & mask.high;
106169689Skan    }
107169689Skan
108169689Skan  return r;
109169689Skan}
110169689Skan
111169689Skan/* Constructs long integer from tree CST.  The extra bits over the precision of
112169689Skan   the number are filled with sign bit if CST is signed, and with zeros if it
113169689Skan   is unsigned.  */
114169689Skan
115169689Skandouble_int
116169689Skantree_to_double_int (tree cst)
117169689Skan{
118169689Skan  /* We do not need to call double_int_restrict here to ensure the semantics as
119169689Skan     described, as this is the default one for trees.  */
120169689Skan  return TREE_INT_CST (cst);
121169689Skan}
122169689Skan
123169689Skan/* Returns true if CST fits in unsigned HOST_WIDE_INT.  */
124169689Skan
125169689Skanbool
126169689Skandouble_int_fits_in_uhwi_p (double_int cst)
127169689Skan{
128169689Skan  return cst.high == 0;
129169689Skan}
130169689Skan
131169689Skan/* Returns true if CST fits in signed HOST_WIDE_INT.  */
132169689Skan
133169689Skanbool
134169689Skandouble_int_fits_in_shwi_p (double_int cst)
135169689Skan{
136169689Skan  if (cst.high == 0)
137169689Skan    return (HOST_WIDE_INT) cst.low >= 0;
138169689Skan  else if (cst.high == -1)
139169689Skan    return (HOST_WIDE_INT) cst.low < 0;
140169689Skan  else
141169689Skan    return false;
142169689Skan}
143169689Skan
144169689Skan/* Returns true if CST fits in HOST_WIDE_INT if UNS is false, or in
145169689Skan   unsigned HOST_WIDE_INT if UNS is true.  */
146169689Skan
147169689Skanbool
148169689Skandouble_int_fits_in_hwi_p (double_int cst, bool uns)
149169689Skan{
150169689Skan  if (uns)
151169689Skan    return double_int_fits_in_uhwi_p (cst);
152169689Skan  else
153169689Skan    return double_int_fits_in_shwi_p (cst);
154169689Skan}
155169689Skan
156169689Skan/* Returns value of CST as a signed number.  CST must satisfy
157169689Skan   double_int_fits_in_shwi_p.  */
158169689Skan
159169689SkanHOST_WIDE_INT
160169689Skandouble_int_to_shwi (double_int cst)
161169689Skan{
162169689Skan  return (HOST_WIDE_INT) cst.low;
163169689Skan}
164169689Skan
165169689Skan/* Returns value of CST as an unsigned number.  CST must satisfy
166169689Skan   double_int_fits_in_uhwi_p.  */
167169689Skan
168169689Skanunsigned HOST_WIDE_INT
169169689Skandouble_int_to_uhwi (double_int cst)
170169689Skan{
171169689Skan  return cst.low;
172169689Skan}
173169689Skan
174169689Skan/* Returns A * B.  */
175169689Skan
176169689Skandouble_int
177169689Skandouble_int_mul (double_int a, double_int b)
178169689Skan{
179169689Skan  double_int ret;
180169689Skan  mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
181169689Skan  return ret;
182169689Skan}
183169689Skan
184169689Skan/* Returns A + B.  */
185169689Skan
186169689Skandouble_int
187169689Skandouble_int_add (double_int a, double_int b)
188169689Skan{
189169689Skan  double_int ret;
190169689Skan  add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
191169689Skan  return ret;
192169689Skan}
193169689Skan
194169689Skan/* Returns -A.  */
195169689Skan
196169689Skandouble_int
197169689Skandouble_int_neg (double_int a)
198169689Skan{
199169689Skan  double_int ret;
200169689Skan  neg_double (a.low, a.high, &ret.low, &ret.high);
201169689Skan  return ret;
202169689Skan}
203169689Skan
204169689Skan/* Returns A / B (computed as unsigned depending on UNS, and rounded as
205169689Skan   specified by CODE).  CODE is enum tree_code in fact, but double_int.h
206169689Skan   must be included before tree.h.  The remainder after the division is
207169689Skan   stored to MOD.  */
208169689Skan
209169689Skandouble_int
210169689Skandouble_int_divmod (double_int a, double_int b, bool uns, unsigned code,
211169689Skan		   double_int *mod)
212169689Skan{
213169689Skan  double_int ret;
214169689Skan
215169689Skan  div_and_round_double (code, uns, a.low, a.high, b.low, b.high,
216169689Skan			&ret.low, &ret.high, &mod->low, &mod->high);
217169689Skan  return ret;
218169689Skan}
219169689Skan
220169689Skan/* The same as double_int_divmod with UNS = false.  */
221169689Skan
222169689Skandouble_int
223169689Skandouble_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod)
224169689Skan{
225169689Skan  return double_int_divmod (a, b, false, code, mod);
226169689Skan}
227169689Skan
228169689Skan/* The same as double_int_divmod with UNS = true.  */
229169689Skan
230169689Skandouble_int
231169689Skandouble_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod)
232169689Skan{
233169689Skan  return double_int_divmod (a, b, true, code, mod);
234169689Skan}
235169689Skan
236169689Skan/* Returns A / B (computed as unsigned depending on UNS, and rounded as
237169689Skan   specified by CODE).  CODE is enum tree_code in fact, but double_int.h
238169689Skan   must be included before tree.h.  */
239169689Skan
240169689Skandouble_int
241169689Skandouble_int_div (double_int a, double_int b, bool uns, unsigned code)
242169689Skan{
243169689Skan  double_int mod;
244169689Skan
245169689Skan  return double_int_divmod (a, b, uns, code, &mod);
246169689Skan}
247169689Skan
248169689Skan/* The same as double_int_div with UNS = false.  */
249169689Skan
250169689Skandouble_int
251169689Skandouble_int_sdiv (double_int a, double_int b, unsigned code)
252169689Skan{
253169689Skan  return double_int_div (a, b, false, code);
254169689Skan}
255169689Skan
256169689Skan/* The same as double_int_div with UNS = true.  */
257169689Skan
258169689Skandouble_int
259169689Skandouble_int_udiv (double_int a, double_int b, unsigned code)
260169689Skan{
261169689Skan  return double_int_div (a, b, true, code);
262169689Skan}
263169689Skan
264169689Skan/* Returns A % B (computed as unsigned depending on UNS, and rounded as
265169689Skan   specified by CODE).  CODE is enum tree_code in fact, but double_int.h
266169689Skan   must be included before tree.h.  */
267169689Skan
268169689Skandouble_int
269169689Skandouble_int_mod (double_int a, double_int b, bool uns, unsigned code)
270169689Skan{
271169689Skan  double_int mod;
272169689Skan
273169689Skan  double_int_divmod (a, b, uns, code, &mod);
274169689Skan  return mod;
275169689Skan}
276169689Skan
277169689Skan/* The same as double_int_mod with UNS = false.  */
278169689Skan
279169689Skandouble_int
280169689Skandouble_int_smod (double_int a, double_int b, unsigned code)
281169689Skan{
282169689Skan  return double_int_mod (a, b, false, code);
283169689Skan}
284169689Skan
285169689Skan/* The same as double_int_mod with UNS = true.  */
286169689Skan
287169689Skandouble_int
288169689Skandouble_int_umod (double_int a, double_int b, unsigned code)
289169689Skan{
290169689Skan  return double_int_mod (a, b, true, code);
291169689Skan}
292169689Skan
293169689Skan/* Constructs tree in type TYPE from with value given by CST.  */
294169689Skan
295169689Skantree
296169689Skandouble_int_to_tree (tree type, double_int cst)
297169689Skan{
298169689Skan  cst = double_int_ext (cst, TYPE_PRECISION (type), TYPE_UNSIGNED (type));
299169689Skan
300169689Skan  return build_int_cst_wide (type, cst.low, cst.high);
301169689Skan}
302169689Skan
303169689Skan/* Returns true if CST is negative.  Of course, CST is considered to
304169689Skan   be signed.  */
305169689Skan
306169689Skanbool
307169689Skandouble_int_negative_p (double_int cst)
308169689Skan{
309169689Skan  return cst.high < 0;
310169689Skan}
311169689Skan
312169689Skan/* Returns -1 if A < B, 0 if A == B and 1 if A > B.  Signedness of the
313169689Skan   comparison is given by UNS.  */
314169689Skan
315169689Skanint
316169689Skandouble_int_cmp (double_int a, double_int b, bool uns)
317169689Skan{
318169689Skan  if (uns)
319169689Skan    return double_int_ucmp (a, b);
320169689Skan  else
321169689Skan    return double_int_scmp (a, b);
322169689Skan}
323169689Skan
324169689Skan/* Compares two unsigned values A and B.  Returns -1 if A < B, 0 if A == B,
325169689Skan   and 1 if A > B.  */
326169689Skan
327169689Skanint
328169689Skandouble_int_ucmp (double_int a, double_int b)
329169689Skan{
330169689Skan  if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high)
331169689Skan    return -1;
332169689Skan  if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high)
333169689Skan    return 1;
334169689Skan  if (a.low < b.low)
335169689Skan    return -1;
336169689Skan  if (a.low > b.low)
337169689Skan    return 1;
338169689Skan
339169689Skan  return 0;
340169689Skan}
341169689Skan
342169689Skan/* Compares two signed values A and B.  Returns -1 if A < B, 0 if A == B,
343169689Skan   and 1 if A > B.  */
344169689Skan
345169689Skanint
346169689Skandouble_int_scmp (double_int a, double_int b)
347169689Skan{
348169689Skan  if (a.high < b.high)
349169689Skan    return -1;
350169689Skan  if (a.high > b.high)
351169689Skan    return 1;
352169689Skan  if ((HOST_WIDE_INT) a.low < (HOST_WIDE_INT) b.low)
353169689Skan    return -1;
354169689Skan  if ((HOST_WIDE_INT) a.low > (HOST_WIDE_INT) b.low)
355169689Skan    return 1;
356169689Skan
357169689Skan  return 0;
358169689Skan}
359169689Skan
360169689Skan/* Splits last digit of *CST (taken as unsigned) in BASE and returns it.  */
361169689Skan
362169689Skanstatic unsigned
363169689Skandouble_int_split_digit (double_int *cst, unsigned base)
364169689Skan{
365169689Skan  unsigned HOST_WIDE_INT resl, reml;
366169689Skan  HOST_WIDE_INT resh, remh;
367169689Skan
368169689Skan  div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0,
369169689Skan			&resl, &resh, &reml, &remh);
370169689Skan  cst->high = resh;
371169689Skan  cst->low = resl;
372169689Skan
373169689Skan  return reml;
374169689Skan}
375169689Skan
376169689Skan/* Dumps CST to FILE.  If UNS is true, CST is considered to be unsigned,
377169689Skan   otherwise it is signed.  */
378169689Skan
379169689Skanvoid
380169689Skandump_double_int (FILE *file, double_int cst, bool uns)
381169689Skan{
382169689Skan  unsigned digits[100], n;
383169689Skan  int i;
384169689Skan
385169689Skan  if (double_int_zero_p (cst))
386169689Skan    {
387169689Skan      fprintf (file, "0");
388169689Skan      return;
389169689Skan    }
390169689Skan
391169689Skan  if (!uns && double_int_negative_p (cst))
392169689Skan    {
393169689Skan      fprintf (file, "-");
394169689Skan      cst = double_int_neg (cst);
395169689Skan    }
396169689Skan
397169689Skan  for (n = 0; !double_int_zero_p (cst); n++)
398169689Skan    digits[n] = double_int_split_digit (&cst, 10);
399169689Skan  for (i = n - 1; i >= 0; i--)
400169689Skan    fprintf (file, "%u", digits[i]);
401169689Skan}
402