xref: /dragonfly/contrib/gcc-4.7/gcc/double-int.c (revision e4b17023)
1*e4b17023SJohn Marino /* Operations with long integers.
2*e4b17023SJohn Marino    Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
3*e4b17023SJohn Marino 
4*e4b17023SJohn Marino This file is part of GCC.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
7*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
9*e4b17023SJohn Marino later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
12*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*e4b17023SJohn Marino for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
17*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
18*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino #include "config.h"
21*e4b17023SJohn Marino #include "system.h"
22*e4b17023SJohn Marino #include "coretypes.h"
23*e4b17023SJohn Marino #include "tm.h"			/* For SHIFT_COUNT_TRUNCATED.  */
24*e4b17023SJohn Marino #include "tree.h"
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
27*e4b17023SJohn Marino    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
28*e4b17023SJohn Marino    and SUM1.  Then this yields nonzero if overflow occurred during the
29*e4b17023SJohn Marino    addition.
30*e4b17023SJohn Marino 
31*e4b17023SJohn Marino    Overflow occurs if A and B have the same sign, but A and SUM differ in
32*e4b17023SJohn Marino    sign.  Use `^' to test whether signs differ, and `< 0' to isolate the
33*e4b17023SJohn Marino    sign.  */
34*e4b17023SJohn Marino #define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
35*e4b17023SJohn Marino 
36*e4b17023SJohn Marino /* To do constant folding on INTEGER_CST nodes requires two-word arithmetic.
37*e4b17023SJohn Marino    We do that by representing the two-word integer in 4 words, with only
38*e4b17023SJohn Marino    HOST_BITS_PER_WIDE_INT / 2 bits stored in each word, as a positive
39*e4b17023SJohn Marino    number.  The value of the word is LOWPART + HIGHPART * BASE.  */
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino #define LOWPART(x) \
42*e4b17023SJohn Marino   ((x) & (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
43*e4b17023SJohn Marino #define HIGHPART(x) \
44*e4b17023SJohn Marino   ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
45*e4b17023SJohn Marino #define BASE ((unsigned HOST_WIDE_INT) 1 << HOST_BITS_PER_WIDE_INT / 2)
46*e4b17023SJohn Marino 
47*e4b17023SJohn Marino /* Unpack a two-word integer into 4 words.
48*e4b17023SJohn Marino    LOW and HI are the integer, as two `HOST_WIDE_INT' pieces.
49*e4b17023SJohn Marino    WORDS points to the array of HOST_WIDE_INTs.  */
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino static void
encode(HOST_WIDE_INT * words,unsigned HOST_WIDE_INT low,HOST_WIDE_INT hi)52*e4b17023SJohn Marino encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
53*e4b17023SJohn Marino {
54*e4b17023SJohn Marino   words[0] = LOWPART (low);
55*e4b17023SJohn Marino   words[1] = HIGHPART (low);
56*e4b17023SJohn Marino   words[2] = LOWPART (hi);
57*e4b17023SJohn Marino   words[3] = HIGHPART (hi);
58*e4b17023SJohn Marino }
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino /* Pack an array of 4 words into a two-word integer.
61*e4b17023SJohn Marino    WORDS points to the array of words.
62*e4b17023SJohn Marino    The integer is stored into *LOW and *HI as two `HOST_WIDE_INT' pieces.  */
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino static void
decode(HOST_WIDE_INT * words,unsigned HOST_WIDE_INT * low,HOST_WIDE_INT * hi)65*e4b17023SJohn Marino decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
66*e4b17023SJohn Marino 	HOST_WIDE_INT *hi)
67*e4b17023SJohn Marino {
68*e4b17023SJohn Marino   *low = words[0] + words[1] * BASE;
69*e4b17023SJohn Marino   *hi = words[2] + words[3] * BASE;
70*e4b17023SJohn Marino }
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino /* Add two doubleword integers with doubleword result.
73*e4b17023SJohn Marino    Return nonzero if the operation overflows according to UNSIGNED_P.
74*e4b17023SJohn Marino    Each argument is given as two `HOST_WIDE_INT' pieces.
75*e4b17023SJohn Marino    One argument is L1 and H1; the other, L2 and H2.
76*e4b17023SJohn Marino    The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino int
add_double_with_sign(unsigned HOST_WIDE_INT l1,HOST_WIDE_INT h1,unsigned HOST_WIDE_INT l2,HOST_WIDE_INT h2,unsigned HOST_WIDE_INT * lv,HOST_WIDE_INT * hv,bool unsigned_p)79*e4b17023SJohn Marino add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
80*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
81*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
82*e4b17023SJohn Marino 		      bool unsigned_p)
83*e4b17023SJohn Marino {
84*e4b17023SJohn Marino   unsigned HOST_WIDE_INT l;
85*e4b17023SJohn Marino   HOST_WIDE_INT h;
86*e4b17023SJohn Marino 
87*e4b17023SJohn Marino   l = l1 + l2;
88*e4b17023SJohn Marino   h = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) h1
89*e4b17023SJohn Marino 		       + (unsigned HOST_WIDE_INT) h2
90*e4b17023SJohn Marino 		       + (l < l1));
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino   *lv = l;
93*e4b17023SJohn Marino   *hv = h;
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino   if (unsigned_p)
96*e4b17023SJohn Marino     return ((unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1
97*e4b17023SJohn Marino 	    || (h == h1
98*e4b17023SJohn Marino 		&& l < l1));
99*e4b17023SJohn Marino   else
100*e4b17023SJohn Marino     return OVERFLOW_SUM_SIGN (h1, h2, h);
101*e4b17023SJohn Marino }
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino /* Negate a doubleword integer with doubleword result.
104*e4b17023SJohn Marino    Return nonzero if the operation overflows, assuming it's signed.
105*e4b17023SJohn Marino    The argument is given as two `HOST_WIDE_INT' pieces in L1 and H1.
106*e4b17023SJohn Marino    The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
107*e4b17023SJohn Marino 
108*e4b17023SJohn Marino int
neg_double(unsigned HOST_WIDE_INT l1,HOST_WIDE_INT h1,unsigned HOST_WIDE_INT * lv,HOST_WIDE_INT * hv)109*e4b17023SJohn Marino neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
110*e4b17023SJohn Marino 	    unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
111*e4b17023SJohn Marino {
112*e4b17023SJohn Marino   if (l1 == 0)
113*e4b17023SJohn Marino     {
114*e4b17023SJohn Marino       *lv = 0;
115*e4b17023SJohn Marino       *hv = - h1;
116*e4b17023SJohn Marino       return (*hv & h1) < 0;
117*e4b17023SJohn Marino     }
118*e4b17023SJohn Marino   else
119*e4b17023SJohn Marino     {
120*e4b17023SJohn Marino       *lv = -l1;
121*e4b17023SJohn Marino       *hv = ~h1;
122*e4b17023SJohn Marino       return 0;
123*e4b17023SJohn Marino     }
124*e4b17023SJohn Marino }
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino /* Multiply two doubleword integers with doubleword result.
127*e4b17023SJohn Marino    Return nonzero if the operation overflows according to UNSIGNED_P.
128*e4b17023SJohn Marino    Each argument is given as two `HOST_WIDE_INT' pieces.
129*e4b17023SJohn Marino    One argument is L1 and H1; the other, L2 and H2.
130*e4b17023SJohn Marino    The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino int
mul_double_with_sign(unsigned HOST_WIDE_INT l1,HOST_WIDE_INT h1,unsigned HOST_WIDE_INT l2,HOST_WIDE_INT h2,unsigned HOST_WIDE_INT * lv,HOST_WIDE_INT * hv,bool unsigned_p)133*e4b17023SJohn Marino mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
134*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
135*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
136*e4b17023SJohn Marino 		      bool unsigned_p)
137*e4b17023SJohn Marino {
138*e4b17023SJohn Marino   HOST_WIDE_INT arg1[4];
139*e4b17023SJohn Marino   HOST_WIDE_INT arg2[4];
140*e4b17023SJohn Marino   HOST_WIDE_INT prod[4 * 2];
141*e4b17023SJohn Marino   unsigned HOST_WIDE_INT carry;
142*e4b17023SJohn Marino   int i, j, k;
143*e4b17023SJohn Marino   unsigned HOST_WIDE_INT toplow, neglow;
144*e4b17023SJohn Marino   HOST_WIDE_INT tophigh, neghigh;
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino   encode (arg1, l1, h1);
147*e4b17023SJohn Marino   encode (arg2, l2, h2);
148*e4b17023SJohn Marino 
149*e4b17023SJohn Marino   memset (prod, 0, sizeof prod);
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino   for (i = 0; i < 4; i++)
152*e4b17023SJohn Marino     {
153*e4b17023SJohn Marino       carry = 0;
154*e4b17023SJohn Marino       for (j = 0; j < 4; j++)
155*e4b17023SJohn Marino 	{
156*e4b17023SJohn Marino 	  k = i + j;
157*e4b17023SJohn Marino 	  /* This product is <= 0xFFFE0001, the sum <= 0xFFFF0000.  */
158*e4b17023SJohn Marino 	  carry += arg1[i] * arg2[j];
159*e4b17023SJohn Marino 	  /* Since prod[p] < 0xFFFF, this sum <= 0xFFFFFFFF.  */
160*e4b17023SJohn Marino 	  carry += prod[k];
161*e4b17023SJohn Marino 	  prod[k] = LOWPART (carry);
162*e4b17023SJohn Marino 	  carry = HIGHPART (carry);
163*e4b17023SJohn Marino 	}
164*e4b17023SJohn Marino       prod[i + 4] = carry;
165*e4b17023SJohn Marino     }
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino   decode (prod, lv, hv);
168*e4b17023SJohn Marino   decode (prod + 4, &toplow, &tophigh);
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino   /* Unsigned overflow is immediate.  */
171*e4b17023SJohn Marino   if (unsigned_p)
172*e4b17023SJohn Marino     return (toplow | tophigh) != 0;
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino   /* Check for signed overflow by calculating the signed representation of the
175*e4b17023SJohn Marino      top half of the result; it should agree with the low half's sign bit.  */
176*e4b17023SJohn Marino   if (h1 < 0)
177*e4b17023SJohn Marino     {
178*e4b17023SJohn Marino       neg_double (l2, h2, &neglow, &neghigh);
179*e4b17023SJohn Marino       add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
180*e4b17023SJohn Marino     }
181*e4b17023SJohn Marino   if (h2 < 0)
182*e4b17023SJohn Marino     {
183*e4b17023SJohn Marino       neg_double (l1, h1, &neglow, &neghigh);
184*e4b17023SJohn Marino       add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
185*e4b17023SJohn Marino     }
186*e4b17023SJohn Marino   return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
187*e4b17023SJohn Marino }
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino /* Shift the doubleword integer in L1, H1 right by COUNT places
190*e4b17023SJohn Marino    keeping only PREC bits of result.  ARITH nonzero specifies
191*e4b17023SJohn Marino    arithmetic shifting; otherwise use logical shift.
192*e4b17023SJohn Marino    Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino static void
rshift_double(unsigned HOST_WIDE_INT l1,HOST_WIDE_INT h1,unsigned HOST_WIDE_INT count,unsigned int prec,unsigned HOST_WIDE_INT * lv,HOST_WIDE_INT * hv,bool arith)195*e4b17023SJohn Marino rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
196*e4b17023SJohn Marino 	       unsigned HOST_WIDE_INT count, unsigned int prec,
197*e4b17023SJohn Marino 	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
198*e4b17023SJohn Marino 	       bool arith)
199*e4b17023SJohn Marino {
200*e4b17023SJohn Marino   unsigned HOST_WIDE_INT signmask;
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino   signmask = (arith
203*e4b17023SJohn Marino 	      ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
204*e4b17023SJohn Marino 	      : 0);
205*e4b17023SJohn Marino 
206*e4b17023SJohn Marino   if (SHIFT_COUNT_TRUNCATED)
207*e4b17023SJohn Marino     count %= prec;
208*e4b17023SJohn Marino 
209*e4b17023SJohn Marino   if (count >= 2 * HOST_BITS_PER_WIDE_INT)
210*e4b17023SJohn Marino     {
211*e4b17023SJohn Marino       /* Shifting by the host word size is undefined according to the
212*e4b17023SJohn Marino 	 ANSI standard, so we must handle this as a special case.  */
213*e4b17023SJohn Marino       *hv = 0;
214*e4b17023SJohn Marino       *lv = 0;
215*e4b17023SJohn Marino     }
216*e4b17023SJohn Marino   else if (count >= HOST_BITS_PER_WIDE_INT)
217*e4b17023SJohn Marino     {
218*e4b17023SJohn Marino       *hv = 0;
219*e4b17023SJohn Marino       *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
220*e4b17023SJohn Marino     }
221*e4b17023SJohn Marino   else
222*e4b17023SJohn Marino     {
223*e4b17023SJohn Marino       *hv = (unsigned HOST_WIDE_INT) h1 >> count;
224*e4b17023SJohn Marino       *lv = ((l1 >> count)
225*e4b17023SJohn Marino 	     | ((unsigned HOST_WIDE_INT) h1
226*e4b17023SJohn Marino 		<< (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
227*e4b17023SJohn Marino     }
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino   /* Zero / sign extend all bits that are beyond the precision.  */
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino   if (count >= prec)
232*e4b17023SJohn Marino     {
233*e4b17023SJohn Marino       *hv = signmask;
234*e4b17023SJohn Marino       *lv = signmask;
235*e4b17023SJohn Marino     }
236*e4b17023SJohn Marino   else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
237*e4b17023SJohn Marino     ;
238*e4b17023SJohn Marino   else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
239*e4b17023SJohn Marino     {
240*e4b17023SJohn Marino       *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
241*e4b17023SJohn Marino       *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
242*e4b17023SJohn Marino     }
243*e4b17023SJohn Marino   else
244*e4b17023SJohn Marino     {
245*e4b17023SJohn Marino       *hv = signmask;
246*e4b17023SJohn Marino       *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
247*e4b17023SJohn Marino       *lv |= signmask << (prec - count);
248*e4b17023SJohn Marino     }
249*e4b17023SJohn Marino }
250*e4b17023SJohn Marino 
251*e4b17023SJohn Marino /* Shift the doubleword integer in L1, H1 left by COUNT places
252*e4b17023SJohn Marino    keeping only PREC bits of result.
253*e4b17023SJohn Marino    Shift right if COUNT is negative.
254*e4b17023SJohn Marino    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
255*e4b17023SJohn Marino    Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
256*e4b17023SJohn Marino 
257*e4b17023SJohn Marino void
lshift_double(unsigned HOST_WIDE_INT l1,HOST_WIDE_INT h1,HOST_WIDE_INT count,unsigned int prec,unsigned HOST_WIDE_INT * lv,HOST_WIDE_INT * hv,bool arith)258*e4b17023SJohn Marino lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
259*e4b17023SJohn Marino 	       HOST_WIDE_INT count, unsigned int prec,
260*e4b17023SJohn Marino 	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool arith)
261*e4b17023SJohn Marino {
262*e4b17023SJohn Marino   unsigned HOST_WIDE_INT signmask;
263*e4b17023SJohn Marino 
264*e4b17023SJohn Marino   if (count < 0)
265*e4b17023SJohn Marino     {
266*e4b17023SJohn Marino       rshift_double (l1, h1, absu_hwi (count), prec, lv, hv, arith);
267*e4b17023SJohn Marino       return;
268*e4b17023SJohn Marino     }
269*e4b17023SJohn Marino 
270*e4b17023SJohn Marino   if (SHIFT_COUNT_TRUNCATED)
271*e4b17023SJohn Marino     count %= prec;
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino   if (count >= 2 * HOST_BITS_PER_WIDE_INT)
274*e4b17023SJohn Marino     {
275*e4b17023SJohn Marino       /* Shifting by the host word size is undefined according to the
276*e4b17023SJohn Marino 	 ANSI standard, so we must handle this as a special case.  */
277*e4b17023SJohn Marino       *hv = 0;
278*e4b17023SJohn Marino       *lv = 0;
279*e4b17023SJohn Marino     }
280*e4b17023SJohn Marino   else if (count >= HOST_BITS_PER_WIDE_INT)
281*e4b17023SJohn Marino     {
282*e4b17023SJohn Marino       *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
283*e4b17023SJohn Marino       *lv = 0;
284*e4b17023SJohn Marino     }
285*e4b17023SJohn Marino   else
286*e4b17023SJohn Marino     {
287*e4b17023SJohn Marino       *hv = (((unsigned HOST_WIDE_INT) h1 << count)
288*e4b17023SJohn Marino 	     | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
289*e4b17023SJohn Marino       *lv = l1 << count;
290*e4b17023SJohn Marino     }
291*e4b17023SJohn Marino 
292*e4b17023SJohn Marino   /* Sign extend all bits that are beyond the precision.  */
293*e4b17023SJohn Marino 
294*e4b17023SJohn Marino   signmask = -((prec > HOST_BITS_PER_WIDE_INT
295*e4b17023SJohn Marino 		? ((unsigned HOST_WIDE_INT) *hv
296*e4b17023SJohn Marino 		   >> (prec - HOST_BITS_PER_WIDE_INT - 1))
297*e4b17023SJohn Marino 		: (*lv >> (prec - 1))) & 1);
298*e4b17023SJohn Marino 
299*e4b17023SJohn Marino   if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
300*e4b17023SJohn Marino     ;
301*e4b17023SJohn Marino   else if (prec >= HOST_BITS_PER_WIDE_INT)
302*e4b17023SJohn Marino     {
303*e4b17023SJohn Marino       *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
304*e4b17023SJohn Marino       *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
305*e4b17023SJohn Marino     }
306*e4b17023SJohn Marino   else
307*e4b17023SJohn Marino     {
308*e4b17023SJohn Marino       *hv = signmask;
309*e4b17023SJohn Marino       *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
310*e4b17023SJohn Marino       *lv |= signmask << prec;
311*e4b17023SJohn Marino     }
312*e4b17023SJohn Marino }
313*e4b17023SJohn Marino 
314*e4b17023SJohn Marino /* Divide doubleword integer LNUM, HNUM by doubleword integer LDEN, HDEN
315*e4b17023SJohn Marino    for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
316*e4b17023SJohn Marino    CODE is a tree code for a kind of division, one of
317*e4b17023SJohn Marino    TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR, ROUND_DIV_EXPR
318*e4b17023SJohn Marino    or EXACT_DIV_EXPR
319*e4b17023SJohn Marino    It controls how the quotient is rounded to an integer.
320*e4b17023SJohn Marino    Return nonzero if the operation overflows.
321*e4b17023SJohn Marino    UNS nonzero says do unsigned division.  */
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino int
div_and_round_double(unsigned code,int uns,unsigned HOST_WIDE_INT lnum_orig,HOST_WIDE_INT hnum_orig,unsigned HOST_WIDE_INT lden_orig,HOST_WIDE_INT hden_orig,unsigned HOST_WIDE_INT * lquo,HOST_WIDE_INT * hquo,unsigned HOST_WIDE_INT * lrem,HOST_WIDE_INT * hrem)324*e4b17023SJohn Marino div_and_round_double (unsigned code, int uns,
325*e4b17023SJohn Marino 		      /* num == numerator == dividend */
326*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT lnum_orig,
327*e4b17023SJohn Marino 		      HOST_WIDE_INT hnum_orig,
328*e4b17023SJohn Marino 		      /* den == denominator == divisor */
329*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT lden_orig,
330*e4b17023SJohn Marino 		      HOST_WIDE_INT hden_orig,
331*e4b17023SJohn Marino 		      unsigned HOST_WIDE_INT *lquo,
332*e4b17023SJohn Marino 		      HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
333*e4b17023SJohn Marino 		      HOST_WIDE_INT *hrem)
334*e4b17023SJohn Marino {
335*e4b17023SJohn Marino   int quo_neg = 0;
336*e4b17023SJohn Marino   HOST_WIDE_INT num[4 + 1];	/* extra element for scaling.  */
337*e4b17023SJohn Marino   HOST_WIDE_INT den[4], quo[4];
338*e4b17023SJohn Marino   int i, j;
339*e4b17023SJohn Marino   unsigned HOST_WIDE_INT work;
340*e4b17023SJohn Marino   unsigned HOST_WIDE_INT carry = 0;
341*e4b17023SJohn Marino   unsigned HOST_WIDE_INT lnum = lnum_orig;
342*e4b17023SJohn Marino   HOST_WIDE_INT hnum = hnum_orig;
343*e4b17023SJohn Marino   unsigned HOST_WIDE_INT lden = lden_orig;
344*e4b17023SJohn Marino   HOST_WIDE_INT hden = hden_orig;
345*e4b17023SJohn Marino   int overflow = 0;
346*e4b17023SJohn Marino 
347*e4b17023SJohn Marino   if (hden == 0 && lden == 0)
348*e4b17023SJohn Marino     overflow = 1, lden = 1;
349*e4b17023SJohn Marino 
350*e4b17023SJohn Marino   /* Calculate quotient sign and convert operands to unsigned.  */
351*e4b17023SJohn Marino   if (!uns)
352*e4b17023SJohn Marino     {
353*e4b17023SJohn Marino       if (hnum < 0)
354*e4b17023SJohn Marino 	{
355*e4b17023SJohn Marino 	  quo_neg = ~ quo_neg;
356*e4b17023SJohn Marino 	  /* (minimum integer) / (-1) is the only overflow case.  */
357*e4b17023SJohn Marino 	  if (neg_double (lnum, hnum, &lnum, &hnum)
358*e4b17023SJohn Marino 	      && ((HOST_WIDE_INT) lden & hden) == -1)
359*e4b17023SJohn Marino 	    overflow = 1;
360*e4b17023SJohn Marino 	}
361*e4b17023SJohn Marino       if (hden < 0)
362*e4b17023SJohn Marino 	{
363*e4b17023SJohn Marino 	  quo_neg = ~ quo_neg;
364*e4b17023SJohn Marino 	  neg_double (lden, hden, &lden, &hden);
365*e4b17023SJohn Marino 	}
366*e4b17023SJohn Marino     }
367*e4b17023SJohn Marino 
368*e4b17023SJohn Marino   if (hnum == 0 && hden == 0)
369*e4b17023SJohn Marino     {				/* single precision */
370*e4b17023SJohn Marino       *hquo = *hrem = 0;
371*e4b17023SJohn Marino       /* This unsigned division rounds toward zero.  */
372*e4b17023SJohn Marino       *lquo = lnum / lden;
373*e4b17023SJohn Marino       goto finish_up;
374*e4b17023SJohn Marino     }
375*e4b17023SJohn Marino 
376*e4b17023SJohn Marino   if (hnum == 0)
377*e4b17023SJohn Marino     {				/* trivial case: dividend < divisor */
378*e4b17023SJohn Marino       /* hden != 0 already checked.  */
379*e4b17023SJohn Marino       *hquo = *lquo = 0;
380*e4b17023SJohn Marino       *hrem = hnum;
381*e4b17023SJohn Marino       *lrem = lnum;
382*e4b17023SJohn Marino       goto finish_up;
383*e4b17023SJohn Marino     }
384*e4b17023SJohn Marino 
385*e4b17023SJohn Marino   memset (quo, 0, sizeof quo);
386*e4b17023SJohn Marino 
387*e4b17023SJohn Marino   memset (num, 0, sizeof num);	/* to zero 9th element */
388*e4b17023SJohn Marino   memset (den, 0, sizeof den);
389*e4b17023SJohn Marino 
390*e4b17023SJohn Marino   encode (num, lnum, hnum);
391*e4b17023SJohn Marino   encode (den, lden, hden);
392*e4b17023SJohn Marino 
393*e4b17023SJohn Marino   /* Special code for when the divisor < BASE.  */
394*e4b17023SJohn Marino   if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
395*e4b17023SJohn Marino     {
396*e4b17023SJohn Marino       /* hnum != 0 already checked.  */
397*e4b17023SJohn Marino       for (i = 4 - 1; i >= 0; i--)
398*e4b17023SJohn Marino 	{
399*e4b17023SJohn Marino 	  work = num[i] + carry * BASE;
400*e4b17023SJohn Marino 	  quo[i] = work / lden;
401*e4b17023SJohn Marino 	  carry = work % lden;
402*e4b17023SJohn Marino 	}
403*e4b17023SJohn Marino     }
404*e4b17023SJohn Marino   else
405*e4b17023SJohn Marino     {
406*e4b17023SJohn Marino       /* Full double precision division,
407*e4b17023SJohn Marino 	 with thanks to Don Knuth's "Seminumerical Algorithms".  */
408*e4b17023SJohn Marino       int num_hi_sig, den_hi_sig;
409*e4b17023SJohn Marino       unsigned HOST_WIDE_INT quo_est, scale;
410*e4b17023SJohn Marino 
411*e4b17023SJohn Marino       /* Find the highest nonzero divisor digit.  */
412*e4b17023SJohn Marino       for (i = 4 - 1;; i--)
413*e4b17023SJohn Marino 	if (den[i] != 0)
414*e4b17023SJohn Marino 	  {
415*e4b17023SJohn Marino 	    den_hi_sig = i;
416*e4b17023SJohn Marino 	    break;
417*e4b17023SJohn Marino 	  }
418*e4b17023SJohn Marino 
419*e4b17023SJohn Marino       /* Insure that the first digit of the divisor is at least BASE/2.
420*e4b17023SJohn Marino 	 This is required by the quotient digit estimation algorithm.  */
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino       scale = BASE / (den[den_hi_sig] + 1);
423*e4b17023SJohn Marino       if (scale > 1)
424*e4b17023SJohn Marino 	{		/* scale divisor and dividend */
425*e4b17023SJohn Marino 	  carry = 0;
426*e4b17023SJohn Marino 	  for (i = 0; i <= 4 - 1; i++)
427*e4b17023SJohn Marino 	    {
428*e4b17023SJohn Marino 	      work = (num[i] * scale) + carry;
429*e4b17023SJohn Marino 	      num[i] = LOWPART (work);
430*e4b17023SJohn Marino 	      carry = HIGHPART (work);
431*e4b17023SJohn Marino 	    }
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino 	  num[4] = carry;
434*e4b17023SJohn Marino 	  carry = 0;
435*e4b17023SJohn Marino 	  for (i = 0; i <= 4 - 1; i++)
436*e4b17023SJohn Marino 	    {
437*e4b17023SJohn Marino 	      work = (den[i] * scale) + carry;
438*e4b17023SJohn Marino 	      den[i] = LOWPART (work);
439*e4b17023SJohn Marino 	      carry = HIGHPART (work);
440*e4b17023SJohn Marino 	      if (den[i] != 0) den_hi_sig = i;
441*e4b17023SJohn Marino 	    }
442*e4b17023SJohn Marino 	}
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino       num_hi_sig = 4;
445*e4b17023SJohn Marino 
446*e4b17023SJohn Marino       /* Main loop */
447*e4b17023SJohn Marino       for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
448*e4b17023SJohn Marino 	{
449*e4b17023SJohn Marino 	  /* Guess the next quotient digit, quo_est, by dividing the first
450*e4b17023SJohn Marino 	     two remaining dividend digits by the high order quotient digit.
451*e4b17023SJohn Marino 	     quo_est is never low and is at most 2 high.  */
452*e4b17023SJohn Marino 	  unsigned HOST_WIDE_INT tmp;
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino 	  num_hi_sig = i + den_hi_sig + 1;
455*e4b17023SJohn Marino 	  work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
456*e4b17023SJohn Marino 	  if (num[num_hi_sig] != den[den_hi_sig])
457*e4b17023SJohn Marino 	    quo_est = work / den[den_hi_sig];
458*e4b17023SJohn Marino 	  else
459*e4b17023SJohn Marino 	    quo_est = BASE - 1;
460*e4b17023SJohn Marino 
461*e4b17023SJohn Marino 	  /* Refine quo_est so it's usually correct, and at most one high.  */
462*e4b17023SJohn Marino 	  tmp = work - quo_est * den[den_hi_sig];
463*e4b17023SJohn Marino 	  if (tmp < BASE
464*e4b17023SJohn Marino 	      && (den[den_hi_sig - 1] * quo_est
465*e4b17023SJohn Marino 		  > (tmp * BASE + num[num_hi_sig - 2])))
466*e4b17023SJohn Marino 	    quo_est--;
467*e4b17023SJohn Marino 
468*e4b17023SJohn Marino 	  /* Try QUO_EST as the quotient digit, by multiplying the
469*e4b17023SJohn Marino 	     divisor by QUO_EST and subtracting from the remaining dividend.
470*e4b17023SJohn Marino 	     Keep in mind that QUO_EST is the I - 1st digit.  */
471*e4b17023SJohn Marino 
472*e4b17023SJohn Marino 	  carry = 0;
473*e4b17023SJohn Marino 	  for (j = 0; j <= den_hi_sig; j++)
474*e4b17023SJohn Marino 	    {
475*e4b17023SJohn Marino 	      work = quo_est * den[j] + carry;
476*e4b17023SJohn Marino 	      carry = HIGHPART (work);
477*e4b17023SJohn Marino 	      work = num[i + j] - LOWPART (work);
478*e4b17023SJohn Marino 	      num[i + j] = LOWPART (work);
479*e4b17023SJohn Marino 	      carry += HIGHPART (work) != 0;
480*e4b17023SJohn Marino 	    }
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino 	  /* If quo_est was high by one, then num[i] went negative and
483*e4b17023SJohn Marino 	     we need to correct things.  */
484*e4b17023SJohn Marino 	  if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
485*e4b17023SJohn Marino 	    {
486*e4b17023SJohn Marino 	      quo_est--;
487*e4b17023SJohn Marino 	      carry = 0;		/* add divisor back in */
488*e4b17023SJohn Marino 	      for (j = 0; j <= den_hi_sig; j++)
489*e4b17023SJohn Marino 		{
490*e4b17023SJohn Marino 		  work = num[i + j] + den[j] + carry;
491*e4b17023SJohn Marino 		  carry = HIGHPART (work);
492*e4b17023SJohn Marino 		  num[i + j] = LOWPART (work);
493*e4b17023SJohn Marino 		}
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino 	      num [num_hi_sig] += carry;
496*e4b17023SJohn Marino 	    }
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino 	  /* Store the quotient digit.  */
499*e4b17023SJohn Marino 	  quo[i] = quo_est;
500*e4b17023SJohn Marino 	}
501*e4b17023SJohn Marino     }
502*e4b17023SJohn Marino 
503*e4b17023SJohn Marino   decode (quo, lquo, hquo);
504*e4b17023SJohn Marino 
505*e4b17023SJohn Marino  finish_up:
506*e4b17023SJohn Marino   /* If result is negative, make it so.  */
507*e4b17023SJohn Marino   if (quo_neg)
508*e4b17023SJohn Marino     neg_double (*lquo, *hquo, lquo, hquo);
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino   /* Compute trial remainder:  rem = num - (quo * den)  */
511*e4b17023SJohn Marino   mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
512*e4b17023SJohn Marino   neg_double (*lrem, *hrem, lrem, hrem);
513*e4b17023SJohn Marino   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
514*e4b17023SJohn Marino 
515*e4b17023SJohn Marino   switch (code)
516*e4b17023SJohn Marino     {
517*e4b17023SJohn Marino     case TRUNC_DIV_EXPR:
518*e4b17023SJohn Marino     case TRUNC_MOD_EXPR:	/* round toward zero */
519*e4b17023SJohn Marino     case EXACT_DIV_EXPR:	/* for this one, it shouldn't matter */
520*e4b17023SJohn Marino       return overflow;
521*e4b17023SJohn Marino 
522*e4b17023SJohn Marino     case FLOOR_DIV_EXPR:
523*e4b17023SJohn Marino     case FLOOR_MOD_EXPR:	/* round toward negative infinity */
524*e4b17023SJohn Marino       if (quo_neg && (*lrem != 0 || *hrem != 0))   /* ratio < 0 && rem != 0 */
525*e4b17023SJohn Marino 	{
526*e4b17023SJohn Marino 	  /* quo = quo - 1;  */
527*e4b17023SJohn Marino 	  add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT)  -1,
528*e4b17023SJohn Marino 		      lquo, hquo);
529*e4b17023SJohn Marino 	}
530*e4b17023SJohn Marino       else
531*e4b17023SJohn Marino 	return overflow;
532*e4b17023SJohn Marino       break;
533*e4b17023SJohn Marino 
534*e4b17023SJohn Marino     case CEIL_DIV_EXPR:
535*e4b17023SJohn Marino     case CEIL_MOD_EXPR:		/* round toward positive infinity */
536*e4b17023SJohn Marino       if (!quo_neg && (*lrem != 0 || *hrem != 0))  /* ratio > 0 && rem != 0 */
537*e4b17023SJohn Marino 	{
538*e4b17023SJohn Marino 	  add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
539*e4b17023SJohn Marino 		      lquo, hquo);
540*e4b17023SJohn Marino 	}
541*e4b17023SJohn Marino       else
542*e4b17023SJohn Marino 	return overflow;
543*e4b17023SJohn Marino       break;
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino     case ROUND_DIV_EXPR:
546*e4b17023SJohn Marino     case ROUND_MOD_EXPR:	/* round to closest integer */
547*e4b17023SJohn Marino       {
548*e4b17023SJohn Marino 	unsigned HOST_WIDE_INT labs_rem = *lrem;
549*e4b17023SJohn Marino 	HOST_WIDE_INT habs_rem = *hrem;
550*e4b17023SJohn Marino 	unsigned HOST_WIDE_INT labs_den = lden, ltwice;
551*e4b17023SJohn Marino 	HOST_WIDE_INT habs_den = hden, htwice;
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino 	/* Get absolute values.  */
554*e4b17023SJohn Marino 	if (*hrem < 0)
555*e4b17023SJohn Marino 	  neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
556*e4b17023SJohn Marino 	if (hden < 0)
557*e4b17023SJohn Marino 	  neg_double (lden, hden, &labs_den, &habs_den);
558*e4b17023SJohn Marino 
559*e4b17023SJohn Marino 	/* If (2 * abs (lrem) >= abs (lden)), adjust the quotient.  */
560*e4b17023SJohn Marino 	mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0,
561*e4b17023SJohn Marino 		    labs_rem, habs_rem, &ltwice, &htwice);
562*e4b17023SJohn Marino 
563*e4b17023SJohn Marino 	if (((unsigned HOST_WIDE_INT) habs_den
564*e4b17023SJohn Marino 	     < (unsigned HOST_WIDE_INT) htwice)
565*e4b17023SJohn Marino 	    || (((unsigned HOST_WIDE_INT) habs_den
566*e4b17023SJohn Marino 		 == (unsigned HOST_WIDE_INT) htwice)
567*e4b17023SJohn Marino 		&& (labs_den <= ltwice)))
568*e4b17023SJohn Marino 	  {
569*e4b17023SJohn Marino 	    if (*hquo < 0)
570*e4b17023SJohn Marino 	      /* quo = quo - 1;  */
571*e4b17023SJohn Marino 	      add_double (*lquo, *hquo,
572*e4b17023SJohn Marino 			  (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);
573*e4b17023SJohn Marino 	    else
574*e4b17023SJohn Marino 	      /* quo = quo + 1; */
575*e4b17023SJohn Marino 	      add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
576*e4b17023SJohn Marino 			  lquo, hquo);
577*e4b17023SJohn Marino 	  }
578*e4b17023SJohn Marino 	else
579*e4b17023SJohn Marino 	  return overflow;
580*e4b17023SJohn Marino       }
581*e4b17023SJohn Marino       break;
582*e4b17023SJohn Marino 
583*e4b17023SJohn Marino     default:
584*e4b17023SJohn Marino       gcc_unreachable ();
585*e4b17023SJohn Marino     }
586*e4b17023SJohn Marino 
587*e4b17023SJohn Marino   /* Compute true remainder:  rem = num - (quo * den)  */
588*e4b17023SJohn Marino   mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
589*e4b17023SJohn Marino   neg_double (*lrem, *hrem, lrem, hrem);
590*e4b17023SJohn Marino   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
591*e4b17023SJohn Marino   return overflow;
592*e4b17023SJohn Marino }
593*e4b17023SJohn Marino 
594*e4b17023SJohn Marino 
595*e4b17023SJohn Marino /* Returns mask for PREC bits.  */
596*e4b17023SJohn Marino 
597*e4b17023SJohn Marino double_int
double_int_mask(unsigned prec)598*e4b17023SJohn Marino double_int_mask (unsigned prec)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino   unsigned HOST_WIDE_INT m;
601*e4b17023SJohn Marino   double_int mask;
602*e4b17023SJohn Marino 
603*e4b17023SJohn Marino   if (prec > HOST_BITS_PER_WIDE_INT)
604*e4b17023SJohn Marino     {
605*e4b17023SJohn Marino       prec -= HOST_BITS_PER_WIDE_INT;
606*e4b17023SJohn Marino       m = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
607*e4b17023SJohn Marino       mask.high = (HOST_WIDE_INT) m;
608*e4b17023SJohn Marino       mask.low = ALL_ONES;
609*e4b17023SJohn Marino     }
610*e4b17023SJohn Marino   else
611*e4b17023SJohn Marino     {
612*e4b17023SJohn Marino       mask.high = 0;
613*e4b17023SJohn Marino       mask.low = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
614*e4b17023SJohn Marino     }
615*e4b17023SJohn Marino 
616*e4b17023SJohn Marino   return mask;
617*e4b17023SJohn Marino }
618*e4b17023SJohn Marino 
619*e4b17023SJohn Marino /* Clears the bits of CST over the precision PREC.  If UNS is false, the bits
620*e4b17023SJohn Marino    outside of the precision are set to the sign bit (i.e., the PREC-th one),
621*e4b17023SJohn Marino    otherwise they are set to zero.
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino    This corresponds to returning the value represented by PREC lowermost bits
624*e4b17023SJohn Marino    of CST, with the given signedness.  */
625*e4b17023SJohn Marino 
626*e4b17023SJohn Marino double_int
double_int_ext(double_int cst,unsigned prec,bool uns)627*e4b17023SJohn Marino double_int_ext (double_int cst, unsigned prec, bool uns)
628*e4b17023SJohn Marino {
629*e4b17023SJohn Marino   if (uns)
630*e4b17023SJohn Marino     return double_int_zext (cst, prec);
631*e4b17023SJohn Marino   else
632*e4b17023SJohn Marino     return double_int_sext (cst, prec);
633*e4b17023SJohn Marino }
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino /* The same as double_int_ext with UNS = true.  */
636*e4b17023SJohn Marino 
637*e4b17023SJohn Marino double_int
double_int_zext(double_int cst,unsigned prec)638*e4b17023SJohn Marino double_int_zext (double_int cst, unsigned prec)
639*e4b17023SJohn Marino {
640*e4b17023SJohn Marino   double_int mask = double_int_mask (prec);
641*e4b17023SJohn Marino   double_int r;
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino   r.low = cst.low & mask.low;
644*e4b17023SJohn Marino   r.high = cst.high & mask.high;
645*e4b17023SJohn Marino 
646*e4b17023SJohn Marino   return r;
647*e4b17023SJohn Marino }
648*e4b17023SJohn Marino 
649*e4b17023SJohn Marino /* The same as double_int_ext with UNS = false.  */
650*e4b17023SJohn Marino 
651*e4b17023SJohn Marino double_int
double_int_sext(double_int cst,unsigned prec)652*e4b17023SJohn Marino double_int_sext (double_int cst, unsigned prec)
653*e4b17023SJohn Marino {
654*e4b17023SJohn Marino   double_int mask = double_int_mask (prec);
655*e4b17023SJohn Marino   double_int r;
656*e4b17023SJohn Marino   unsigned HOST_WIDE_INT snum;
657*e4b17023SJohn Marino 
658*e4b17023SJohn Marino   if (prec <= HOST_BITS_PER_WIDE_INT)
659*e4b17023SJohn Marino     snum = cst.low;
660*e4b17023SJohn Marino   else
661*e4b17023SJohn Marino     {
662*e4b17023SJohn Marino       prec -= HOST_BITS_PER_WIDE_INT;
663*e4b17023SJohn Marino       snum = (unsigned HOST_WIDE_INT) cst.high;
664*e4b17023SJohn Marino     }
665*e4b17023SJohn Marino   if (((snum >> (prec - 1)) & 1) == 1)
666*e4b17023SJohn Marino     {
667*e4b17023SJohn Marino       r.low = cst.low | ~mask.low;
668*e4b17023SJohn Marino       r.high = cst.high | ~mask.high;
669*e4b17023SJohn Marino     }
670*e4b17023SJohn Marino   else
671*e4b17023SJohn Marino     {
672*e4b17023SJohn Marino       r.low = cst.low & mask.low;
673*e4b17023SJohn Marino       r.high = cst.high & mask.high;
674*e4b17023SJohn Marino     }
675*e4b17023SJohn Marino 
676*e4b17023SJohn Marino   return r;
677*e4b17023SJohn Marino }
678*e4b17023SJohn Marino 
679*e4b17023SJohn Marino /* Returns true if CST fits in signed HOST_WIDE_INT.  */
680*e4b17023SJohn Marino 
681*e4b17023SJohn Marino bool
double_int_fits_in_shwi_p(double_int cst)682*e4b17023SJohn Marino double_int_fits_in_shwi_p (double_int cst)
683*e4b17023SJohn Marino {
684*e4b17023SJohn Marino   if (cst.high == 0)
685*e4b17023SJohn Marino     return (HOST_WIDE_INT) cst.low >= 0;
686*e4b17023SJohn Marino   else if (cst.high == -1)
687*e4b17023SJohn Marino     return (HOST_WIDE_INT) cst.low < 0;
688*e4b17023SJohn Marino   else
689*e4b17023SJohn Marino     return false;
690*e4b17023SJohn Marino }
691*e4b17023SJohn Marino 
692*e4b17023SJohn Marino /* Returns true if CST fits in HOST_WIDE_INT if UNS is false, or in
693*e4b17023SJohn Marino    unsigned HOST_WIDE_INT if UNS is true.  */
694*e4b17023SJohn Marino 
695*e4b17023SJohn Marino bool
double_int_fits_in_hwi_p(double_int cst,bool uns)696*e4b17023SJohn Marino double_int_fits_in_hwi_p (double_int cst, bool uns)
697*e4b17023SJohn Marino {
698*e4b17023SJohn Marino   if (uns)
699*e4b17023SJohn Marino     return double_int_fits_in_uhwi_p (cst);
700*e4b17023SJohn Marino   else
701*e4b17023SJohn Marino     return double_int_fits_in_shwi_p (cst);
702*e4b17023SJohn Marino }
703*e4b17023SJohn Marino 
704*e4b17023SJohn Marino /* Returns A * B.  */
705*e4b17023SJohn Marino 
706*e4b17023SJohn Marino double_int
double_int_mul(double_int a,double_int b)707*e4b17023SJohn Marino double_int_mul (double_int a, double_int b)
708*e4b17023SJohn Marino {
709*e4b17023SJohn Marino   double_int ret;
710*e4b17023SJohn Marino   mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
711*e4b17023SJohn Marino   return ret;
712*e4b17023SJohn Marino }
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino /* Returns A * B. If the operation overflows according to UNSIGNED_P,
715*e4b17023SJohn Marino    *OVERFLOW is set to nonzero.  */
716*e4b17023SJohn Marino 
717*e4b17023SJohn Marino double_int
double_int_mul_with_sign(double_int a,double_int b,bool unsigned_p,int * overflow)718*e4b17023SJohn Marino double_int_mul_with_sign (double_int a, double_int b,
719*e4b17023SJohn Marino                           bool unsigned_p, int *overflow)
720*e4b17023SJohn Marino {
721*e4b17023SJohn Marino   double_int ret;
722*e4b17023SJohn Marino   *overflow = mul_double_with_sign (a.low, a.high, b.low, b.high,
723*e4b17023SJohn Marino                                     &ret.low, &ret.high, unsigned_p);
724*e4b17023SJohn Marino   return ret;
725*e4b17023SJohn Marino }
726*e4b17023SJohn Marino 
727*e4b17023SJohn Marino /* Returns A + B.  */
728*e4b17023SJohn Marino 
729*e4b17023SJohn Marino double_int
double_int_add(double_int a,double_int b)730*e4b17023SJohn Marino double_int_add (double_int a, double_int b)
731*e4b17023SJohn Marino {
732*e4b17023SJohn Marino   double_int ret;
733*e4b17023SJohn Marino   add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
734*e4b17023SJohn Marino   return ret;
735*e4b17023SJohn Marino }
736*e4b17023SJohn Marino 
737*e4b17023SJohn Marino /* Returns A - B.  */
738*e4b17023SJohn Marino 
739*e4b17023SJohn Marino double_int
double_int_sub(double_int a,double_int b)740*e4b17023SJohn Marino double_int_sub (double_int a, double_int b)
741*e4b17023SJohn Marino {
742*e4b17023SJohn Marino   double_int ret;
743*e4b17023SJohn Marino   neg_double (b.low, b.high, &b.low, &b.high);
744*e4b17023SJohn Marino   add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
745*e4b17023SJohn Marino   return ret;
746*e4b17023SJohn Marino }
747*e4b17023SJohn Marino 
748*e4b17023SJohn Marino /* Returns -A.  */
749*e4b17023SJohn Marino 
750*e4b17023SJohn Marino double_int
double_int_neg(double_int a)751*e4b17023SJohn Marino double_int_neg (double_int a)
752*e4b17023SJohn Marino {
753*e4b17023SJohn Marino   double_int ret;
754*e4b17023SJohn Marino   neg_double (a.low, a.high, &ret.low, &ret.high);
755*e4b17023SJohn Marino   return ret;
756*e4b17023SJohn Marino }
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino /* Returns A / B (computed as unsigned depending on UNS, and rounded as
759*e4b17023SJohn Marino    specified by CODE).  CODE is enum tree_code in fact, but double_int.h
760*e4b17023SJohn Marino    must be included before tree.h.  The remainder after the division is
761*e4b17023SJohn Marino    stored to MOD.  */
762*e4b17023SJohn Marino 
763*e4b17023SJohn Marino double_int
double_int_divmod(double_int a,double_int b,bool uns,unsigned code,double_int * mod)764*e4b17023SJohn Marino double_int_divmod (double_int a, double_int b, bool uns, unsigned code,
765*e4b17023SJohn Marino 		   double_int *mod)
766*e4b17023SJohn Marino {
767*e4b17023SJohn Marino   double_int ret;
768*e4b17023SJohn Marino 
769*e4b17023SJohn Marino   div_and_round_double (code, uns, a.low, a.high,
770*e4b17023SJohn Marino 			b.low, b.high, &ret.low, &ret.high,
771*e4b17023SJohn Marino 			&mod->low, &mod->high);
772*e4b17023SJohn Marino   return ret;
773*e4b17023SJohn Marino }
774*e4b17023SJohn Marino 
775*e4b17023SJohn Marino /* The same as double_int_divmod with UNS = false.  */
776*e4b17023SJohn Marino 
777*e4b17023SJohn Marino double_int
double_int_sdivmod(double_int a,double_int b,unsigned code,double_int * mod)778*e4b17023SJohn Marino double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod)
779*e4b17023SJohn Marino {
780*e4b17023SJohn Marino   return double_int_divmod (a, b, false, code, mod);
781*e4b17023SJohn Marino }
782*e4b17023SJohn Marino 
783*e4b17023SJohn Marino /* The same as double_int_divmod with UNS = true.  */
784*e4b17023SJohn Marino 
785*e4b17023SJohn Marino double_int
double_int_udivmod(double_int a,double_int b,unsigned code,double_int * mod)786*e4b17023SJohn Marino double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod)
787*e4b17023SJohn Marino {
788*e4b17023SJohn Marino   return double_int_divmod (a, b, true, code, mod);
789*e4b17023SJohn Marino }
790*e4b17023SJohn Marino 
791*e4b17023SJohn Marino /* Returns A / B (computed as unsigned depending on UNS, and rounded as
792*e4b17023SJohn Marino    specified by CODE).  CODE is enum tree_code in fact, but double_int.h
793*e4b17023SJohn Marino    must be included before tree.h.  */
794*e4b17023SJohn Marino 
795*e4b17023SJohn Marino double_int
double_int_div(double_int a,double_int b,bool uns,unsigned code)796*e4b17023SJohn Marino double_int_div (double_int a, double_int b, bool uns, unsigned code)
797*e4b17023SJohn Marino {
798*e4b17023SJohn Marino   double_int mod;
799*e4b17023SJohn Marino 
800*e4b17023SJohn Marino   return double_int_divmod (a, b, uns, code, &mod);
801*e4b17023SJohn Marino }
802*e4b17023SJohn Marino 
803*e4b17023SJohn Marino /* The same as double_int_div with UNS = false.  */
804*e4b17023SJohn Marino 
805*e4b17023SJohn Marino double_int
double_int_sdiv(double_int a,double_int b,unsigned code)806*e4b17023SJohn Marino double_int_sdiv (double_int a, double_int b, unsigned code)
807*e4b17023SJohn Marino {
808*e4b17023SJohn Marino   return double_int_div (a, b, false, code);
809*e4b17023SJohn Marino }
810*e4b17023SJohn Marino 
811*e4b17023SJohn Marino /* The same as double_int_div with UNS = true.  */
812*e4b17023SJohn Marino 
813*e4b17023SJohn Marino double_int
double_int_udiv(double_int a,double_int b,unsigned code)814*e4b17023SJohn Marino double_int_udiv (double_int a, double_int b, unsigned code)
815*e4b17023SJohn Marino {
816*e4b17023SJohn Marino   return double_int_div (a, b, true, code);
817*e4b17023SJohn Marino }
818*e4b17023SJohn Marino 
819*e4b17023SJohn Marino /* Returns A % B (computed as unsigned depending on UNS, and rounded as
820*e4b17023SJohn Marino    specified by CODE).  CODE is enum tree_code in fact, but double_int.h
821*e4b17023SJohn Marino    must be included before tree.h.  */
822*e4b17023SJohn Marino 
823*e4b17023SJohn Marino double_int
double_int_mod(double_int a,double_int b,bool uns,unsigned code)824*e4b17023SJohn Marino double_int_mod (double_int a, double_int b, bool uns, unsigned code)
825*e4b17023SJohn Marino {
826*e4b17023SJohn Marino   double_int mod;
827*e4b17023SJohn Marino 
828*e4b17023SJohn Marino   double_int_divmod (a, b, uns, code, &mod);
829*e4b17023SJohn Marino   return mod;
830*e4b17023SJohn Marino }
831*e4b17023SJohn Marino 
832*e4b17023SJohn Marino /* The same as double_int_mod with UNS = false.  */
833*e4b17023SJohn Marino 
834*e4b17023SJohn Marino double_int
double_int_smod(double_int a,double_int b,unsigned code)835*e4b17023SJohn Marino double_int_smod (double_int a, double_int b, unsigned code)
836*e4b17023SJohn Marino {
837*e4b17023SJohn Marino   return double_int_mod (a, b, false, code);
838*e4b17023SJohn Marino }
839*e4b17023SJohn Marino 
840*e4b17023SJohn Marino /* The same as double_int_mod with UNS = true.  */
841*e4b17023SJohn Marino 
842*e4b17023SJohn Marino double_int
double_int_umod(double_int a,double_int b,unsigned code)843*e4b17023SJohn Marino double_int_umod (double_int a, double_int b, unsigned code)
844*e4b17023SJohn Marino {
845*e4b17023SJohn Marino   return double_int_mod (a, b, true, code);
846*e4b17023SJohn Marino }
847*e4b17023SJohn Marino 
848*e4b17023SJohn Marino /* Set BITPOS bit in A.  */
849*e4b17023SJohn Marino double_int
double_int_setbit(double_int a,unsigned bitpos)850*e4b17023SJohn Marino double_int_setbit (double_int a, unsigned bitpos)
851*e4b17023SJohn Marino {
852*e4b17023SJohn Marino   if (bitpos < HOST_BITS_PER_WIDE_INT)
853*e4b17023SJohn Marino     a.low |= (unsigned HOST_WIDE_INT) 1 << bitpos;
854*e4b17023SJohn Marino   else
855*e4b17023SJohn Marino     a.high |= (HOST_WIDE_INT) 1 <<  (bitpos - HOST_BITS_PER_WIDE_INT);
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino   return a;
858*e4b17023SJohn Marino }
859*e4b17023SJohn Marino 
860*e4b17023SJohn Marino /* Count trailing zeros in A.  */
861*e4b17023SJohn Marino int
double_int_ctz(double_int a)862*e4b17023SJohn Marino double_int_ctz (double_int a)
863*e4b17023SJohn Marino {
864*e4b17023SJohn Marino   unsigned HOST_WIDE_INT w = a.low ? a.low : (unsigned HOST_WIDE_INT) a.high;
865*e4b17023SJohn Marino   unsigned bits = a.low ? 0 : HOST_BITS_PER_WIDE_INT;
866*e4b17023SJohn Marino   if (!w)
867*e4b17023SJohn Marino     return HOST_BITS_PER_DOUBLE_INT;
868*e4b17023SJohn Marino   bits += ctz_hwi (w);
869*e4b17023SJohn Marino   return bits;
870*e4b17023SJohn Marino }
871*e4b17023SJohn Marino 
872*e4b17023SJohn Marino /* Shift A left by COUNT places keeping only PREC bits of result.  Shift
873*e4b17023SJohn Marino    right if COUNT is negative.  ARITH true specifies arithmetic shifting;
874*e4b17023SJohn Marino    otherwise use logical shift.  */
875*e4b17023SJohn Marino 
876*e4b17023SJohn Marino double_int
double_int_lshift(double_int a,HOST_WIDE_INT count,unsigned int prec,bool arith)877*e4b17023SJohn Marino double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
878*e4b17023SJohn Marino {
879*e4b17023SJohn Marino   double_int ret;
880*e4b17023SJohn Marino   lshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
881*e4b17023SJohn Marino   return ret;
882*e4b17023SJohn Marino }
883*e4b17023SJohn Marino 
884*e4b17023SJohn Marino /* Shift A rigth by COUNT places keeping only PREC bits of result.  Shift
885*e4b17023SJohn Marino    left if COUNT is negative.  ARITH true specifies arithmetic shifting;
886*e4b17023SJohn Marino    otherwise use logical shift.  */
887*e4b17023SJohn Marino 
888*e4b17023SJohn Marino double_int
double_int_rshift(double_int a,HOST_WIDE_INT count,unsigned int prec,bool arith)889*e4b17023SJohn Marino double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
890*e4b17023SJohn Marino {
891*e4b17023SJohn Marino   double_int ret;
892*e4b17023SJohn Marino   lshift_double (a.low, a.high, -count, prec, &ret.low, &ret.high, arith);
893*e4b17023SJohn Marino   return ret;
894*e4b17023SJohn Marino }
895*e4b17023SJohn Marino 
896*e4b17023SJohn Marino /* Rotate  A left by COUNT places keeping only PREC bits of result.
897*e4b17023SJohn Marino    Rotate right if COUNT is negative.  */
898*e4b17023SJohn Marino 
899*e4b17023SJohn Marino double_int
double_int_lrotate(double_int a,HOST_WIDE_INT count,unsigned int prec)900*e4b17023SJohn Marino double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
901*e4b17023SJohn Marino {
902*e4b17023SJohn Marino   double_int t1, t2;
903*e4b17023SJohn Marino 
904*e4b17023SJohn Marino   count %= prec;
905*e4b17023SJohn Marino   if (count < 0)
906*e4b17023SJohn Marino     count += prec;
907*e4b17023SJohn Marino 
908*e4b17023SJohn Marino   t1 = double_int_lshift (a, count, prec, false);
909*e4b17023SJohn Marino   t2 = double_int_rshift (a, prec - count, prec, false);
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino   return double_int_ior (t1, t2);
912*e4b17023SJohn Marino }
913*e4b17023SJohn Marino 
914*e4b17023SJohn Marino /* Rotate A rigth by COUNT places keeping only PREC bits of result.
915*e4b17023SJohn Marino    Rotate right if COUNT is negative.  */
916*e4b17023SJohn Marino 
917*e4b17023SJohn Marino double_int
double_int_rrotate(double_int a,HOST_WIDE_INT count,unsigned int prec)918*e4b17023SJohn Marino double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
919*e4b17023SJohn Marino {
920*e4b17023SJohn Marino   double_int t1, t2;
921*e4b17023SJohn Marino 
922*e4b17023SJohn Marino   count %= prec;
923*e4b17023SJohn Marino   if (count < 0)
924*e4b17023SJohn Marino     count += prec;
925*e4b17023SJohn Marino 
926*e4b17023SJohn Marino   t1 = double_int_rshift (a, count, prec, false);
927*e4b17023SJohn Marino   t2 = double_int_lshift (a, prec - count, prec, false);
928*e4b17023SJohn Marino 
929*e4b17023SJohn Marino   return double_int_ior (t1, t2);
930*e4b17023SJohn Marino }
931*e4b17023SJohn Marino 
932*e4b17023SJohn Marino /* Returns -1 if A < B, 0 if A == B and 1 if A > B.  Signedness of the
933*e4b17023SJohn Marino    comparison is given by UNS.  */
934*e4b17023SJohn Marino 
935*e4b17023SJohn Marino int
double_int_cmp(double_int a,double_int b,bool uns)936*e4b17023SJohn Marino double_int_cmp (double_int a, double_int b, bool uns)
937*e4b17023SJohn Marino {
938*e4b17023SJohn Marino   if (uns)
939*e4b17023SJohn Marino     return double_int_ucmp (a, b);
940*e4b17023SJohn Marino   else
941*e4b17023SJohn Marino     return double_int_scmp (a, b);
942*e4b17023SJohn Marino }
943*e4b17023SJohn Marino 
944*e4b17023SJohn Marino /* Compares two unsigned values A and B.  Returns -1 if A < B, 0 if A == B,
945*e4b17023SJohn Marino    and 1 if A > B.  */
946*e4b17023SJohn Marino 
947*e4b17023SJohn Marino int
double_int_ucmp(double_int a,double_int b)948*e4b17023SJohn Marino double_int_ucmp (double_int a, double_int b)
949*e4b17023SJohn Marino {
950*e4b17023SJohn Marino   if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high)
951*e4b17023SJohn Marino     return -1;
952*e4b17023SJohn Marino   if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high)
953*e4b17023SJohn Marino     return 1;
954*e4b17023SJohn Marino   if (a.low < b.low)
955*e4b17023SJohn Marino     return -1;
956*e4b17023SJohn Marino   if (a.low > b.low)
957*e4b17023SJohn Marino     return 1;
958*e4b17023SJohn Marino 
959*e4b17023SJohn Marino   return 0;
960*e4b17023SJohn Marino }
961*e4b17023SJohn Marino 
962*e4b17023SJohn Marino /* Compares two signed values A and B.  Returns -1 if A < B, 0 if A == B,
963*e4b17023SJohn Marino    and 1 if A > B.  */
964*e4b17023SJohn Marino 
965*e4b17023SJohn Marino int
double_int_scmp(double_int a,double_int b)966*e4b17023SJohn Marino double_int_scmp (double_int a, double_int b)
967*e4b17023SJohn Marino {
968*e4b17023SJohn Marino   if (a.high < b.high)
969*e4b17023SJohn Marino     return -1;
970*e4b17023SJohn Marino   if (a.high > b.high)
971*e4b17023SJohn Marino     return 1;
972*e4b17023SJohn Marino   if (a.low < b.low)
973*e4b17023SJohn Marino     return -1;
974*e4b17023SJohn Marino   if (a.low > b.low)
975*e4b17023SJohn Marino     return 1;
976*e4b17023SJohn Marino 
977*e4b17023SJohn Marino   return 0;
978*e4b17023SJohn Marino }
979*e4b17023SJohn Marino 
980*e4b17023SJohn Marino /* Compares two values A and B.  Returns max value.  Signedness of the
981*e4b17023SJohn Marino    comparison is given by UNS.  */
982*e4b17023SJohn Marino 
983*e4b17023SJohn Marino double_int
double_int_max(double_int a,double_int b,bool uns)984*e4b17023SJohn Marino double_int_max (double_int a, double_int b, bool uns)
985*e4b17023SJohn Marino {
986*e4b17023SJohn Marino   return (double_int_cmp (a, b, uns) == 1) ? a : b;
987*e4b17023SJohn Marino }
988*e4b17023SJohn Marino 
989*e4b17023SJohn Marino /* Compares two signed values A and B.  Returns max value.  */
990*e4b17023SJohn Marino 
double_int_smax(double_int a,double_int b)991*e4b17023SJohn Marino double_int double_int_smax (double_int a, double_int b)
992*e4b17023SJohn Marino {
993*e4b17023SJohn Marino   return (double_int_scmp (a, b) == 1) ? a : b;
994*e4b17023SJohn Marino }
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino /* Compares two unsigned values A and B.  Returns max value.  */
997*e4b17023SJohn Marino 
double_int_umax(double_int a,double_int b)998*e4b17023SJohn Marino double_int double_int_umax (double_int a, double_int b)
999*e4b17023SJohn Marino {
1000*e4b17023SJohn Marino   return (double_int_ucmp (a, b) == 1) ? a : b;
1001*e4b17023SJohn Marino }
1002*e4b17023SJohn Marino 
1003*e4b17023SJohn Marino /* Compares two values A and B.  Returns mix value.  Signedness of the
1004*e4b17023SJohn Marino    comparison is given by UNS.  */
1005*e4b17023SJohn Marino 
double_int_min(double_int a,double_int b,bool uns)1006*e4b17023SJohn Marino double_int double_int_min (double_int a, double_int b, bool uns)
1007*e4b17023SJohn Marino {
1008*e4b17023SJohn Marino   return (double_int_cmp (a, b, uns) == -1) ? a : b;
1009*e4b17023SJohn Marino }
1010*e4b17023SJohn Marino 
1011*e4b17023SJohn Marino /* Compares two signed values A and B.  Returns min value.  */
1012*e4b17023SJohn Marino 
double_int_smin(double_int a,double_int b)1013*e4b17023SJohn Marino double_int double_int_smin (double_int a, double_int b)
1014*e4b17023SJohn Marino {
1015*e4b17023SJohn Marino   return (double_int_scmp (a, b) == -1) ? a : b;
1016*e4b17023SJohn Marino }
1017*e4b17023SJohn Marino 
1018*e4b17023SJohn Marino /* Compares two unsigned values A and B.  Returns min value.  */
1019*e4b17023SJohn Marino 
double_int_umin(double_int a,double_int b)1020*e4b17023SJohn Marino double_int double_int_umin (double_int a, double_int b)
1021*e4b17023SJohn Marino {
1022*e4b17023SJohn Marino   return (double_int_ucmp (a, b) == -1) ? a : b;
1023*e4b17023SJohn Marino }
1024*e4b17023SJohn Marino 
1025*e4b17023SJohn Marino /* Splits last digit of *CST (taken as unsigned) in BASE and returns it.  */
1026*e4b17023SJohn Marino 
1027*e4b17023SJohn Marino static unsigned
double_int_split_digit(double_int * cst,unsigned base)1028*e4b17023SJohn Marino double_int_split_digit (double_int *cst, unsigned base)
1029*e4b17023SJohn Marino {
1030*e4b17023SJohn Marino   unsigned HOST_WIDE_INT resl, reml;
1031*e4b17023SJohn Marino   HOST_WIDE_INT resh, remh;
1032*e4b17023SJohn Marino 
1033*e4b17023SJohn Marino   div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0,
1034*e4b17023SJohn Marino 			&resl, &resh, &reml, &remh);
1035*e4b17023SJohn Marino   cst->high = resh;
1036*e4b17023SJohn Marino   cst->low = resl;
1037*e4b17023SJohn Marino 
1038*e4b17023SJohn Marino   return reml;
1039*e4b17023SJohn Marino }
1040*e4b17023SJohn Marino 
1041*e4b17023SJohn Marino /* Dumps CST to FILE.  If UNS is true, CST is considered to be unsigned,
1042*e4b17023SJohn Marino    otherwise it is signed.  */
1043*e4b17023SJohn Marino 
1044*e4b17023SJohn Marino void
dump_double_int(FILE * file,double_int cst,bool uns)1045*e4b17023SJohn Marino dump_double_int (FILE *file, double_int cst, bool uns)
1046*e4b17023SJohn Marino {
1047*e4b17023SJohn Marino   unsigned digits[100], n;
1048*e4b17023SJohn Marino   int i;
1049*e4b17023SJohn Marino 
1050*e4b17023SJohn Marino   if (double_int_zero_p (cst))
1051*e4b17023SJohn Marino     {
1052*e4b17023SJohn Marino       fprintf (file, "0");
1053*e4b17023SJohn Marino       return;
1054*e4b17023SJohn Marino     }
1055*e4b17023SJohn Marino 
1056*e4b17023SJohn Marino   if (!uns && double_int_negative_p (cst))
1057*e4b17023SJohn Marino     {
1058*e4b17023SJohn Marino       fprintf (file, "-");
1059*e4b17023SJohn Marino       cst = double_int_neg (cst);
1060*e4b17023SJohn Marino     }
1061*e4b17023SJohn Marino 
1062*e4b17023SJohn Marino   for (n = 0; !double_int_zero_p (cst); n++)
1063*e4b17023SJohn Marino     digits[n] = double_int_split_digit (&cst, 10);
1064*e4b17023SJohn Marino   for (i = n - 1; i >= 0; i--)
1065*e4b17023SJohn Marino     fprintf (file, "%u", digits[i]);
1066*e4b17023SJohn Marino }
1067*e4b17023SJohn Marino 
1068*e4b17023SJohn Marino 
1069*e4b17023SJohn Marino /* Sets RESULT to VAL, taken unsigned if UNS is true and as signed
1070*e4b17023SJohn Marino    otherwise.  */
1071*e4b17023SJohn Marino 
1072*e4b17023SJohn Marino void
mpz_set_double_int(mpz_t result,double_int val,bool uns)1073*e4b17023SJohn Marino mpz_set_double_int (mpz_t result, double_int val, bool uns)
1074*e4b17023SJohn Marino {
1075*e4b17023SJohn Marino   bool negate = false;
1076*e4b17023SJohn Marino   unsigned HOST_WIDE_INT vp[2];
1077*e4b17023SJohn Marino 
1078*e4b17023SJohn Marino   if (!uns && double_int_negative_p (val))
1079*e4b17023SJohn Marino     {
1080*e4b17023SJohn Marino       negate = true;
1081*e4b17023SJohn Marino       val = double_int_neg (val);
1082*e4b17023SJohn Marino     }
1083*e4b17023SJohn Marino 
1084*e4b17023SJohn Marino   vp[0] = val.low;
1085*e4b17023SJohn Marino   vp[1] = (unsigned HOST_WIDE_INT) val.high;
1086*e4b17023SJohn Marino   mpz_import (result, 2, -1, sizeof (HOST_WIDE_INT), 0, 0, vp);
1087*e4b17023SJohn Marino 
1088*e4b17023SJohn Marino   if (negate)
1089*e4b17023SJohn Marino     mpz_neg (result, result);
1090*e4b17023SJohn Marino }
1091*e4b17023SJohn Marino 
1092*e4b17023SJohn Marino /* Returns VAL converted to TYPE.  If WRAP is true, then out-of-range
1093*e4b17023SJohn Marino    values of VAL will be wrapped; otherwise, they will be set to the
1094*e4b17023SJohn Marino    appropriate minimum or maximum TYPE bound.  */
1095*e4b17023SJohn Marino 
1096*e4b17023SJohn Marino double_int
mpz_get_double_int(const_tree type,mpz_t val,bool wrap)1097*e4b17023SJohn Marino mpz_get_double_int (const_tree type, mpz_t val, bool wrap)
1098*e4b17023SJohn Marino {
1099*e4b17023SJohn Marino   unsigned HOST_WIDE_INT *vp;
1100*e4b17023SJohn Marino   size_t count, numb;
1101*e4b17023SJohn Marino   double_int res;
1102*e4b17023SJohn Marino 
1103*e4b17023SJohn Marino   if (!wrap)
1104*e4b17023SJohn Marino     {
1105*e4b17023SJohn Marino       mpz_t min, max;
1106*e4b17023SJohn Marino 
1107*e4b17023SJohn Marino       mpz_init (min);
1108*e4b17023SJohn Marino       mpz_init (max);
1109*e4b17023SJohn Marino       get_type_static_bounds (type, min, max);
1110*e4b17023SJohn Marino 
1111*e4b17023SJohn Marino       if (mpz_cmp (val, min) < 0)
1112*e4b17023SJohn Marino 	mpz_set (val, min);
1113*e4b17023SJohn Marino       else if (mpz_cmp (val, max) > 0)
1114*e4b17023SJohn Marino 	mpz_set (val, max);
1115*e4b17023SJohn Marino 
1116*e4b17023SJohn Marino       mpz_clear (min);
1117*e4b17023SJohn Marino       mpz_clear (max);
1118*e4b17023SJohn Marino     }
1119*e4b17023SJohn Marino 
1120*e4b17023SJohn Marino   /* Determine the number of unsigned HOST_WIDE_INT that are required
1121*e4b17023SJohn Marino      for representing the value.  The code to calculate count is
1122*e4b17023SJohn Marino      extracted from the GMP manual, section "Integer Import and Export":
1123*e4b17023SJohn Marino      http://gmplib.org/manual/Integer-Import-and-Export.html  */
1124*e4b17023SJohn Marino   numb = 8*sizeof(HOST_WIDE_INT);
1125*e4b17023SJohn Marino   count = (mpz_sizeinbase (val, 2) + numb-1) / numb;
1126*e4b17023SJohn Marino   if (count < 2)
1127*e4b17023SJohn Marino     count = 2;
1128*e4b17023SJohn Marino   vp = (unsigned HOST_WIDE_INT *) alloca (count * sizeof(HOST_WIDE_INT));
1129*e4b17023SJohn Marino 
1130*e4b17023SJohn Marino   vp[0] = 0;
1131*e4b17023SJohn Marino   vp[1] = 0;
1132*e4b17023SJohn Marino   mpz_export (vp, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, val);
1133*e4b17023SJohn Marino 
1134*e4b17023SJohn Marino   gcc_assert (wrap || count <= 2);
1135*e4b17023SJohn Marino 
1136*e4b17023SJohn Marino   res.low = vp[0];
1137*e4b17023SJohn Marino   res.high = (HOST_WIDE_INT) vp[1];
1138*e4b17023SJohn Marino 
1139*e4b17023SJohn Marino   res = double_int_ext (res, TYPE_PRECISION (type), TYPE_UNSIGNED (type));
1140*e4b17023SJohn Marino   if (mpz_sgn (val) < 0)
1141*e4b17023SJohn Marino     res = double_int_neg (res);
1142*e4b17023SJohn Marino 
1143*e4b17023SJohn Marino   return res;
1144*e4b17023SJohn Marino }
1145