annotate gcc/double-int.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Operations with long integers.
16
kono
parents: 14
diff changeset
2 Copyright (C) 2006-2017 Free Software Foundation, Inc.
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
3
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
5
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Free Software Foundation; either version 3, or (at your option) any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 later version.
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
10
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 for more details.
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
15
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "coretypes.h"
16
kono
parents: 14
diff changeset
23 #include "tm.h" /* For BITS_PER_UNIT and *_BIG_ENDIAN. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "tree.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25
16
kono
parents: 14
diff changeset
26 static int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
kono
parents: 14
diff changeset
27 unsigned HOST_WIDE_INT, HOST_WIDE_INT,
kono
parents: 14
diff changeset
28 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
kono
parents: 14
diff changeset
29 bool);
kono
parents: 14
diff changeset
30
kono
parents: 14
diff changeset
31 #define add_double(l1,h1,l2,h2,lv,hv) \
kono
parents: 14
diff changeset
32 add_double_with_sign (l1, h1, l2, h2, lv, hv, false)
kono
parents: 14
diff changeset
33
kono
parents: 14
diff changeset
34 static int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
kono
parents: 14
diff changeset
35 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
kono
parents: 14
diff changeset
36
kono
parents: 14
diff changeset
37 static int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
kono
parents: 14
diff changeset
38 unsigned HOST_WIDE_INT, HOST_WIDE_INT,
kono
parents: 14
diff changeset
39 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
kono
parents: 14
diff changeset
40 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
kono
parents: 14
diff changeset
41 bool);
kono
parents: 14
diff changeset
42
kono
parents: 14
diff changeset
43 #define mul_double(l1,h1,l2,h2,lv,hv) \
kono
parents: 14
diff changeset
44 mul_double_wide_with_sign (l1, h1, l2, h2, lv, hv, NULL, NULL, false)
kono
parents: 14
diff changeset
45
kono
parents: 14
diff changeset
46 static int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
kono
parents: 14
diff changeset
47 HOST_WIDE_INT, unsigned HOST_WIDE_INT,
kono
parents: 14
diff changeset
48 HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
kono
parents: 14
diff changeset
49 HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
kono
parents: 14
diff changeset
50 HOST_WIDE_INT *);
kono
parents: 14
diff changeset
51
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
52 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
53 overflow. Suppose A, B and SUM have the same respective signs as A1, B1,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
54 and SUM1. Then this yields nonzero if overflow occurred during the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
55 addition.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
56
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
57 Overflow occurs if A and B have the same sign, but A and SUM differ in
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
58 sign. Use `^' to test whether signs differ, and `< 0' to isolate the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
59 sign. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
60 #define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
61
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
62 /* To do constant folding on INTEGER_CST nodes requires two-word arithmetic.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
63 We do that by representing the two-word integer in 4 words, with only
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
64 HOST_BITS_PER_WIDE_INT / 2 bits stored in each word, as a positive
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
65 number. The value of the word is LOWPART + HIGHPART * BASE. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
66
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
67 #define LOWPART(x) \
16
kono
parents: 14
diff changeset
68 ((x) & ((HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
69 #define HIGHPART(x) \
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
70 ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
16
kono
parents: 14
diff changeset
71 #define BASE (HOST_WIDE_INT_1U << HOST_BITS_PER_WIDE_INT / 2)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
72
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
73 /* Unpack a two-word integer into 4 words.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
74 LOW and HI are the integer, as two `HOST_WIDE_INT' pieces.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
75 WORDS points to the array of HOST_WIDE_INTs. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
76
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
77 static void
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
78 encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
79 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
80 words[0] = LOWPART (low);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
81 words[1] = HIGHPART (low);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
82 words[2] = LOWPART (hi);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
83 words[3] = HIGHPART (hi);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
84 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
85
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
86 /* Pack an array of 4 words into a two-word integer.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
87 WORDS points to the array of words.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
88 The integer is stored into *LOW and *HI as two `HOST_WIDE_INT' pieces. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
89
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
90 static void
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
91 decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
92 HOST_WIDE_INT *hi)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
93 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
94 *low = words[0] + words[1] * BASE;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
95 *hi = words[2] + words[3] * BASE;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
96 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
97
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
98 /* Add two doubleword integers with doubleword result.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
99 Return nonzero if the operation overflows according to UNSIGNED_P.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
100 Each argument is given as two `HOST_WIDE_INT' pieces.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
101 One argument is L1 and H1; the other, L2 and H2.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
102 The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
103
16
kono
parents: 14
diff changeset
104 static int
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
105 add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
106 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
107 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
108 bool unsigned_p)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
109 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
110 unsigned HOST_WIDE_INT l;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
111 HOST_WIDE_INT h;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
112
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
113 l = l1 + l2;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
114 h = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) h1
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
115 + (unsigned HOST_WIDE_INT) h2
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
116 + (l < l1));
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
117
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
118 *lv = l;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
119 *hv = h;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
120
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
121 if (unsigned_p)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
122 return ((unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
123 || (h == h1
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
124 && l < l1));
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
125 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
126 return OVERFLOW_SUM_SIGN (h1, h2, h);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
127 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
128
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
129 /* Negate a doubleword integer with doubleword result.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
130 Return nonzero if the operation overflows, assuming it's signed.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
131 The argument is given as two `HOST_WIDE_INT' pieces in L1 and H1.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
132 The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
133
16
kono
parents: 14
diff changeset
134 static int
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
135 neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
136 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
137 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
138 if (l1 == 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
139 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
140 *lv = 0;
16
kono
parents: 14
diff changeset
141 *hv = - (unsigned HOST_WIDE_INT) h1;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
142 return (*hv & h1) < 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
143 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
144 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
145 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
146 *lv = -l1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
147 *hv = ~h1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
148 return 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
149 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
150 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
151
16
kono
parents: 14
diff changeset
152 /* Multiply two doubleword integers with quadword result.
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
153 Return nonzero if the operation overflows according to UNSIGNED_P.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
154 Each argument is given as two `HOST_WIDE_INT' pieces.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
155 One argument is L1 and H1; the other, L2 and H2.
16
kono
parents: 14
diff changeset
156 The value is stored as four `HOST_WIDE_INT' pieces in *LV and *HV,
kono
parents: 14
diff changeset
157 *LW and *HW.
kono
parents: 14
diff changeset
158 If lw is NULL then only the low part and no overflow is computed. */
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
159
16
kono
parents: 14
diff changeset
160 static int
kono
parents: 14
diff changeset
161 mul_double_wide_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
kono
parents: 14
diff changeset
162 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
kono
parents: 14
diff changeset
163 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
kono
parents: 14
diff changeset
164 unsigned HOST_WIDE_INT *lw, HOST_WIDE_INT *hw,
kono
parents: 14
diff changeset
165 bool unsigned_p)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
166 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
167 HOST_WIDE_INT arg1[4];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
168 HOST_WIDE_INT arg2[4];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
169 HOST_WIDE_INT prod[4 * 2];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
170 unsigned HOST_WIDE_INT carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
171 int i, j, k;
16
kono
parents: 14
diff changeset
172 unsigned HOST_WIDE_INT neglow;
kono
parents: 14
diff changeset
173 HOST_WIDE_INT neghigh;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
174
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
175 encode (arg1, l1, h1);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
176 encode (arg2, l2, h2);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
177
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
178 memset (prod, 0, sizeof prod);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
179
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
180 for (i = 0; i < 4; i++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
181 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
182 carry = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
183 for (j = 0; j < 4; j++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
184 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
185 k = i + j;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
186 /* This product is <= 0xFFFE0001, the sum <= 0xFFFF0000. */
16
kono
parents: 14
diff changeset
187 carry += (unsigned HOST_WIDE_INT) arg1[i] * arg2[j];
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
188 /* Since prod[p] < 0xFFFF, this sum <= 0xFFFFFFFF. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
189 carry += prod[k];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
190 prod[k] = LOWPART (carry);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
191 carry = HIGHPART (carry);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
192 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
193 prod[i + 4] = carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
194 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
195
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
196 decode (prod, lv, hv);
16
kono
parents: 14
diff changeset
197
kono
parents: 14
diff changeset
198 /* We are not interested in the wide part nor in overflow. */
kono
parents: 14
diff changeset
199 if (lw == NULL)
kono
parents: 14
diff changeset
200 return 0;
kono
parents: 14
diff changeset
201
kono
parents: 14
diff changeset
202 decode (prod + 4, lw, hw);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
203
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
204 /* Unsigned overflow is immediate. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
205 if (unsigned_p)
16
kono
parents: 14
diff changeset
206 return (*lw | *hw) != 0;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
207
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
208 /* Check for signed overflow by calculating the signed representation of the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
209 top half of the result; it should agree with the low half's sign bit. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
210 if (h1 < 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
211 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
212 neg_double (l2, h2, &neglow, &neghigh);
16
kono
parents: 14
diff changeset
213 add_double (neglow, neghigh, *lw, *hw, lw, hw);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
214 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
215 if (h2 < 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
216 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
217 neg_double (l1, h1, &neglow, &neghigh);
16
kono
parents: 14
diff changeset
218 add_double (neglow, neghigh, *lw, *hw, lw, hw);
kono
parents: 14
diff changeset
219 }
kono
parents: 14
diff changeset
220 return (*hv < 0 ? ~(*lw & *hw) : *lw | *hw) != 0;
kono
parents: 14
diff changeset
221 }
kono
parents: 14
diff changeset
222
kono
parents: 14
diff changeset
223 /* Shift the doubleword integer in L1, H1 right by COUNT places
kono
parents: 14
diff changeset
224 keeping only PREC bits of result. ARITH nonzero specifies
kono
parents: 14
diff changeset
225 arithmetic shifting; otherwise use logical shift.
kono
parents: 14
diff changeset
226 Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
kono
parents: 14
diff changeset
227
kono
parents: 14
diff changeset
228 static void
kono
parents: 14
diff changeset
229 rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
kono
parents: 14
diff changeset
230 unsigned HOST_WIDE_INT count, unsigned int prec,
kono
parents: 14
diff changeset
231 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
kono
parents: 14
diff changeset
232 bool arith)
kono
parents: 14
diff changeset
233 {
kono
parents: 14
diff changeset
234 unsigned HOST_WIDE_INT signmask;
kono
parents: 14
diff changeset
235
kono
parents: 14
diff changeset
236 signmask = (arith
kono
parents: 14
diff changeset
237 ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
kono
parents: 14
diff changeset
238 : 0);
kono
parents: 14
diff changeset
239
kono
parents: 14
diff changeset
240 if (count >= HOST_BITS_PER_DOUBLE_INT)
kono
parents: 14
diff changeset
241 {
kono
parents: 14
diff changeset
242 /* Shifting by the host word size is undefined according to the
kono
parents: 14
diff changeset
243 ANSI standard, so we must handle this as a special case. */
kono
parents: 14
diff changeset
244 *hv = 0;
kono
parents: 14
diff changeset
245 *lv = 0;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
246 }
16
kono
parents: 14
diff changeset
247 else if (count >= HOST_BITS_PER_WIDE_INT)
kono
parents: 14
diff changeset
248 {
kono
parents: 14
diff changeset
249 *hv = 0;
kono
parents: 14
diff changeset
250 *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
kono
parents: 14
diff changeset
251 }
kono
parents: 14
diff changeset
252 else
kono
parents: 14
diff changeset
253 {
kono
parents: 14
diff changeset
254 *hv = (unsigned HOST_WIDE_INT) h1 >> count;
kono
parents: 14
diff changeset
255 *lv = ((l1 >> count)
kono
parents: 14
diff changeset
256 | ((unsigned HOST_WIDE_INT) h1
kono
parents: 14
diff changeset
257 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
kono
parents: 14
diff changeset
258 }
kono
parents: 14
diff changeset
259
kono
parents: 14
diff changeset
260 /* Zero / sign extend all bits that are beyond the precision. */
kono
parents: 14
diff changeset
261
kono
parents: 14
diff changeset
262 if (count >= prec)
kono
parents: 14
diff changeset
263 {
kono
parents: 14
diff changeset
264 *hv = signmask;
kono
parents: 14
diff changeset
265 *lv = signmask;
kono
parents: 14
diff changeset
266 }
kono
parents: 14
diff changeset
267 else if ((prec - count) >= HOST_BITS_PER_DOUBLE_INT)
kono
parents: 14
diff changeset
268 ;
kono
parents: 14
diff changeset
269 else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
kono
parents: 14
diff changeset
270 {
kono
parents: 14
diff changeset
271 *hv &= ~(HOST_WIDE_INT_M1U << (prec - count - HOST_BITS_PER_WIDE_INT));
kono
parents: 14
diff changeset
272 *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
kono
parents: 14
diff changeset
273 }
kono
parents: 14
diff changeset
274 else
kono
parents: 14
diff changeset
275 {
kono
parents: 14
diff changeset
276 *hv = signmask;
kono
parents: 14
diff changeset
277 *lv &= ~(HOST_WIDE_INT_M1U << (prec - count));
kono
parents: 14
diff changeset
278 *lv |= signmask << (prec - count);
kono
parents: 14
diff changeset
279 }
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
280 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
281
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
282 /* Shift the doubleword integer in L1, H1 left by COUNT places
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
283 keeping only PREC bits of result.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
284 Shift right if COUNT is negative.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
285 ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
286 Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
287
16
kono
parents: 14
diff changeset
288 static void
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
289 lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
16
kono
parents: 14
diff changeset
290 unsigned HOST_WIDE_INT count, unsigned int prec,
kono
parents: 14
diff changeset
291 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
292 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
293 unsigned HOST_WIDE_INT signmask;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
294
16
kono
parents: 14
diff changeset
295 if (count >= HOST_BITS_PER_DOUBLE_INT)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
296 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
297 /* Shifting by the host word size is undefined according to the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
298 ANSI standard, so we must handle this as a special case. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
299 *hv = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
300 *lv = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
301 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
302 else if (count >= HOST_BITS_PER_WIDE_INT)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
303 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
304 *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
305 *lv = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
306 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
307 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
308 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
309 *hv = (((unsigned HOST_WIDE_INT) h1 << count)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
310 | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
311 *lv = l1 << count;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
312 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
313
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
314 /* Sign extend all bits that are beyond the precision. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
315
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
316 signmask = -((prec > HOST_BITS_PER_WIDE_INT
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
317 ? ((unsigned HOST_WIDE_INT) *hv
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
318 >> (prec - HOST_BITS_PER_WIDE_INT - 1))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
319 : (*lv >> (prec - 1))) & 1);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
320
16
kono
parents: 14
diff changeset
321 if (prec >= HOST_BITS_PER_DOUBLE_INT)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
322 ;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
323 else if (prec >= HOST_BITS_PER_WIDE_INT)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
324 {
16
kono
parents: 14
diff changeset
325 *hv &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
326 *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
327 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
328 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
329 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
330 *hv = signmask;
16
kono
parents: 14
diff changeset
331 *lv &= ~(HOST_WIDE_INT_M1U << prec);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
332 *lv |= signmask << prec;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
333 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
334 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
335
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
336 /* Divide doubleword integer LNUM, HNUM by doubleword integer LDEN, HDEN
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
337 for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
338 CODE is a tree code for a kind of division, one of
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
339 TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR, ROUND_DIV_EXPR
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
340 or EXACT_DIV_EXPR
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
341 It controls how the quotient is rounded to an integer.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
342 Return nonzero if the operation overflows.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
343 UNS nonzero says do unsigned division. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
344
16
kono
parents: 14
diff changeset
345 static int
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
346 div_and_round_double (unsigned code, int uns,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
347 /* num == numerator == dividend */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
348 unsigned HOST_WIDE_INT lnum_orig,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
349 HOST_WIDE_INT hnum_orig,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
350 /* den == denominator == divisor */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
351 unsigned HOST_WIDE_INT lden_orig,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
352 HOST_WIDE_INT hden_orig,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
353 unsigned HOST_WIDE_INT *lquo,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
354 HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
355 HOST_WIDE_INT *hrem)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
356 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
357 int quo_neg = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
358 HOST_WIDE_INT num[4 + 1]; /* extra element for scaling. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
359 HOST_WIDE_INT den[4], quo[4];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
360 int i, j;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
361 unsigned HOST_WIDE_INT work;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
362 unsigned HOST_WIDE_INT carry = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
363 unsigned HOST_WIDE_INT lnum = lnum_orig;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
364 HOST_WIDE_INT hnum = hnum_orig;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
365 unsigned HOST_WIDE_INT lden = lden_orig;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
366 HOST_WIDE_INT hden = hden_orig;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
367 int overflow = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
368
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
369 if (hden == 0 && lden == 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
370 overflow = 1, lden = 1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
371
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
372 /* Calculate quotient sign and convert operands to unsigned. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
373 if (!uns)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
374 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
375 if (hnum < 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
376 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
377 quo_neg = ~ quo_neg;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
378 /* (minimum integer) / (-1) is the only overflow case. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
379 if (neg_double (lnum, hnum, &lnum, &hnum)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
380 && ((HOST_WIDE_INT) lden & hden) == -1)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
381 overflow = 1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
382 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
383 if (hden < 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
384 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
385 quo_neg = ~ quo_neg;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
386 neg_double (lden, hden, &lden, &hden);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
387 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
388 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
389
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
390 if (hnum == 0 && hden == 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
391 { /* single precision */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
392 *hquo = *hrem = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
393 /* This unsigned division rounds toward zero. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
394 *lquo = lnum / lden;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
395 goto finish_up;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
396 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
397
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
398 if (hnum == 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
399 { /* trivial case: dividend < divisor */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
400 /* hden != 0 already checked. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
401 *hquo = *lquo = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
402 *hrem = hnum;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
403 *lrem = lnum;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
404 goto finish_up;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
405 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
406
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
407 memset (quo, 0, sizeof quo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
408
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
409 memset (num, 0, sizeof num); /* to zero 9th element */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
410 memset (den, 0, sizeof den);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
411
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
412 encode (num, lnum, hnum);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
413 encode (den, lden, hden);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
414
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
415 /* Special code for when the divisor < BASE. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
416 if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
417 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
418 /* hnum != 0 already checked. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
419 for (i = 4 - 1; i >= 0; i--)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
420 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
421 work = num[i] + carry * BASE;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
422 quo[i] = work / lden;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
423 carry = work % lden;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
424 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
425 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
426 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
427 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
428 /* Full double precision division,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
429 with thanks to Don Knuth's "Seminumerical Algorithms". */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
430 int num_hi_sig, den_hi_sig;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
431 unsigned HOST_WIDE_INT quo_est, scale;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
432
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
433 /* Find the highest nonzero divisor digit. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
434 for (i = 4 - 1;; i--)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
435 if (den[i] != 0)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
436 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
437 den_hi_sig = i;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
438 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
439 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
440
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
441 /* Insure that the first digit of the divisor is at least BASE/2.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
442 This is required by the quotient digit estimation algorithm. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
443
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
444 scale = BASE / (den[den_hi_sig] + 1);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
445 if (scale > 1)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
446 { /* scale divisor and dividend */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
447 carry = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
448 for (i = 0; i <= 4 - 1; i++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
449 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
450 work = (num[i] * scale) + carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
451 num[i] = LOWPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
452 carry = HIGHPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
453 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
454
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
455 num[4] = carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
456 carry = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
457 for (i = 0; i <= 4 - 1; i++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
458 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
459 work = (den[i] * scale) + carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
460 den[i] = LOWPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
461 carry = HIGHPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
462 if (den[i] != 0) den_hi_sig = i;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
463 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
464 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
465
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
466 num_hi_sig = 4;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
467
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
468 /* Main loop */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
469 for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
470 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
471 /* Guess the next quotient digit, quo_est, by dividing the first
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
472 two remaining dividend digits by the high order quotient digit.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
473 quo_est is never low and is at most 2 high. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
474 unsigned HOST_WIDE_INT tmp;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
475
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
476 num_hi_sig = i + den_hi_sig + 1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
477 work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
478 if (num[num_hi_sig] != den[den_hi_sig])
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
479 quo_est = work / den[den_hi_sig];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
480 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
481 quo_est = BASE - 1;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
482
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
483 /* Refine quo_est so it's usually correct, and at most one high. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
484 tmp = work - quo_est * den[den_hi_sig];
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
485 if (tmp < BASE
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
486 && (den[den_hi_sig - 1] * quo_est
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
487 > (tmp * BASE + num[num_hi_sig - 2])))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
488 quo_est--;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
489
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
490 /* Try QUO_EST as the quotient digit, by multiplying the
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
491 divisor by QUO_EST and subtracting from the remaining dividend.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
492 Keep in mind that QUO_EST is the I - 1st digit. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
493
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
494 carry = 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
495 for (j = 0; j <= den_hi_sig; j++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
496 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
497 work = quo_est * den[j] + carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
498 carry = HIGHPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
499 work = num[i + j] - LOWPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
500 num[i + j] = LOWPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
501 carry += HIGHPART (work) != 0;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
502 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
503
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
504 /* If quo_est was high by one, then num[i] went negative and
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
505 we need to correct things. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
506 if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
507 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
508 quo_est--;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
509 carry = 0; /* add divisor back in */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
510 for (j = 0; j <= den_hi_sig; j++)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
511 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
512 work = num[i + j] + den[j] + carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
513 carry = HIGHPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
514 num[i + j] = LOWPART (work);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
515 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
516
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
517 num [num_hi_sig] += carry;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
518 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
519
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
520 /* Store the quotient digit. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
521 quo[i] = quo_est;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
522 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
523 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
524
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
525 decode (quo, lquo, hquo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
526
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
527 finish_up:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
528 /* If result is negative, make it so. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
529 if (quo_neg)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
530 neg_double (*lquo, *hquo, lquo, hquo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
531
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
532 /* Compute trial remainder: rem = num - (quo * den) */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
533 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
534 neg_double (*lrem, *hrem, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
535 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
536
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
537 switch (code)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
538 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
539 case TRUNC_DIV_EXPR:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
540 case TRUNC_MOD_EXPR: /* round toward zero */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
541 case EXACT_DIV_EXPR: /* for this one, it shouldn't matter */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
542 return overflow;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
543
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
544 case FLOOR_DIV_EXPR:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
545 case FLOOR_MOD_EXPR: /* round toward negative infinity */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
546 if (quo_neg && (*lrem != 0 || *hrem != 0)) /* ratio < 0 && rem != 0 */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
547 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
548 /* quo = quo - 1; */
16
kono
parents: 14
diff changeset
549 add_double (*lquo, *hquo, HOST_WIDE_INT_M1, HOST_WIDE_INT_M1,
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
550 lquo, hquo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
551 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
552 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
553 return overflow;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
554 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
555
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
556 case CEIL_DIV_EXPR:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
557 case CEIL_MOD_EXPR: /* round toward positive infinity */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
558 if (!quo_neg && (*lrem != 0 || *hrem != 0)) /* ratio > 0 && rem != 0 */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
559 {
16
kono
parents: 14
diff changeset
560 add_double (*lquo, *hquo, HOST_WIDE_INT_1, HOST_WIDE_INT_0,
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
561 lquo, hquo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
562 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
563 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
564 return overflow;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
565 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
566
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
567 case ROUND_DIV_EXPR:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
568 case ROUND_MOD_EXPR: /* round to closest integer */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
569 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
570 unsigned HOST_WIDE_INT labs_rem = *lrem;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
571 HOST_WIDE_INT habs_rem = *hrem;
16
kono
parents: 14
diff changeset
572 unsigned HOST_WIDE_INT labs_den = lden, lnegabs_rem, ldiff;
kono
parents: 14
diff changeset
573 HOST_WIDE_INT habs_den = hden, hnegabs_rem, hdiff;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
574
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
575 /* Get absolute values. */
16
kono
parents: 14
diff changeset
576 if (!uns && *hrem < 0)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
577 neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
16
kono
parents: 14
diff changeset
578 if (!uns && hden < 0)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
579 neg_double (lden, hden, &labs_den, &habs_den);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
580
16
kono
parents: 14
diff changeset
581 /* If abs(rem) >= abs(den) - abs(rem), adjust the quotient. */
kono
parents: 14
diff changeset
582 neg_double (labs_rem, habs_rem, &lnegabs_rem, &hnegabs_rem);
kono
parents: 14
diff changeset
583 add_double (labs_den, habs_den, lnegabs_rem, hnegabs_rem,
kono
parents: 14
diff changeset
584 &ldiff, &hdiff);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
585
16
kono
parents: 14
diff changeset
586 if (((unsigned HOST_WIDE_INT) habs_rem
kono
parents: 14
diff changeset
587 > (unsigned HOST_WIDE_INT) hdiff)
kono
parents: 14
diff changeset
588 || (habs_rem == hdiff && labs_rem >= ldiff))
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
589 {
16
kono
parents: 14
diff changeset
590 if (quo_neg)
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
591 /* quo = quo - 1; */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
592 add_double (*lquo, *hquo,
16
kono
parents: 14
diff changeset
593 HOST_WIDE_INT_M1, HOST_WIDE_INT_M1, lquo, hquo);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
594 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
595 /* quo = quo + 1; */
16
kono
parents: 14
diff changeset
596 add_double (*lquo, *hquo, HOST_WIDE_INT_1, HOST_WIDE_INT_0,
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
597 lquo, hquo);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
598 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
599 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
600 return overflow;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
601 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
602 break;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
603
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
604 default:
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
605 gcc_unreachable ();
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
606 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
607
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
608 /* Compute true remainder: rem = num - (quo * den) */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
609 mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
610 neg_double (*lrem, *hrem, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
611 add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
612 return overflow;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
613 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
614
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
615
16
kono
parents: 14
diff changeset
616 /* Construct from a buffer of length LEN. BUFFER will be read according
kono
parents: 14
diff changeset
617 to byte endianness and word endianness. Only the lower LEN bytes
kono
parents: 14
diff changeset
618 of the result are set; the remaining high bytes are cleared. */
kono
parents: 14
diff changeset
619
kono
parents: 14
diff changeset
620 double_int
kono
parents: 14
diff changeset
621 double_int::from_buffer (const unsigned char *buffer, int len)
kono
parents: 14
diff changeset
622 {
kono
parents: 14
diff changeset
623 double_int result = double_int_zero;
kono
parents: 14
diff changeset
624 int words = len / UNITS_PER_WORD;
kono
parents: 14
diff changeset
625
kono
parents: 14
diff changeset
626 gcc_assert (len * BITS_PER_UNIT <= HOST_BITS_PER_DOUBLE_INT);
kono
parents: 14
diff changeset
627
kono
parents: 14
diff changeset
628 for (int byte = 0; byte < len; byte++)
kono
parents: 14
diff changeset
629 {
kono
parents: 14
diff changeset
630 int offset;
kono
parents: 14
diff changeset
631 int bitpos = byte * BITS_PER_UNIT;
kono
parents: 14
diff changeset
632 unsigned HOST_WIDE_INT value;
kono
parents: 14
diff changeset
633
kono
parents: 14
diff changeset
634 if (len > UNITS_PER_WORD)
kono
parents: 14
diff changeset
635 {
kono
parents: 14
diff changeset
636 int word = byte / UNITS_PER_WORD;
kono
parents: 14
diff changeset
637
kono
parents: 14
diff changeset
638 if (WORDS_BIG_ENDIAN)
kono
parents: 14
diff changeset
639 word = (words - 1) - word;
kono
parents: 14
diff changeset
640
kono
parents: 14
diff changeset
641 offset = word * UNITS_PER_WORD;
kono
parents: 14
diff changeset
642
kono
parents: 14
diff changeset
643 if (BYTES_BIG_ENDIAN)
kono
parents: 14
diff changeset
644 offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
kono
parents: 14
diff changeset
645 else
kono
parents: 14
diff changeset
646 offset += byte % UNITS_PER_WORD;
kono
parents: 14
diff changeset
647 }
kono
parents: 14
diff changeset
648 else
kono
parents: 14
diff changeset
649 offset = BYTES_BIG_ENDIAN ? (len - 1) - byte : byte;
kono
parents: 14
diff changeset
650
kono
parents: 14
diff changeset
651 value = (unsigned HOST_WIDE_INT) buffer[offset];
kono
parents: 14
diff changeset
652
kono
parents: 14
diff changeset
653 if (bitpos < HOST_BITS_PER_WIDE_INT)
kono
parents: 14
diff changeset
654 result.low |= value << bitpos;
kono
parents: 14
diff changeset
655 else
kono
parents: 14
diff changeset
656 result.high |= value << (bitpos - HOST_BITS_PER_WIDE_INT);
kono
parents: 14
diff changeset
657 }
kono
parents: 14
diff changeset
658
kono
parents: 14
diff changeset
659 return result;
kono
parents: 14
diff changeset
660 }
kono
parents: 14
diff changeset
661
kono
parents: 14
diff changeset
662
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 /* Returns mask for PREC bits. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 double_int
16
kono
parents: 14
diff changeset
666 double_int::mask (unsigned prec)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 unsigned HOST_WIDE_INT m;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 double_int mask;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 if (prec > HOST_BITS_PER_WIDE_INT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 prec -= HOST_BITS_PER_WIDE_INT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 m = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 mask.high = (HOST_WIDE_INT) m;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 mask.low = ALL_ONES;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 mask.high = 0;
16
kono
parents: 14
diff changeset
681 mask.low = prec ? ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1 : 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 return mask;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686
16
kono
parents: 14
diff changeset
687 /* Returns a maximum value for signed or unsigned integer
kono
parents: 14
diff changeset
688 of precision PREC. */
kono
parents: 14
diff changeset
689
kono
parents: 14
diff changeset
690 double_int
kono
parents: 14
diff changeset
691 double_int::max_value (unsigned int prec, bool uns)
kono
parents: 14
diff changeset
692 {
kono
parents: 14
diff changeset
693 return double_int::mask (prec - (uns ? 0 : 1));
kono
parents: 14
diff changeset
694 }
kono
parents: 14
diff changeset
695
kono
parents: 14
diff changeset
696 /* Returns a minimum value for signed or unsigned integer
kono
parents: 14
diff changeset
697 of precision PREC. */
kono
parents: 14
diff changeset
698
kono
parents: 14
diff changeset
699 double_int
kono
parents: 14
diff changeset
700 double_int::min_value (unsigned int prec, bool uns)
kono
parents: 14
diff changeset
701 {
kono
parents: 14
diff changeset
702 if (uns)
kono
parents: 14
diff changeset
703 return double_int_zero;
kono
parents: 14
diff changeset
704 return double_int_one.lshift (prec - 1, prec, false);
kono
parents: 14
diff changeset
705 }
kono
parents: 14
diff changeset
706
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 /* Clears the bits of CST over the precision PREC. If UNS is false, the bits
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 outside of the precision are set to the sign bit (i.e., the PREC-th one),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 otherwise they are set to zero.
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
710
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 This corresponds to returning the value represented by PREC lowermost bits
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 of CST, with the given signedness. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 double_int
16
kono
parents: 14
diff changeset
715 double_int::ext (unsigned prec, bool uns) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 if (uns)
16
kono
parents: 14
diff changeset
718 return this->zext (prec);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 else
16
kono
parents: 14
diff changeset
720 return this->sext (prec);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722
16
kono
parents: 14
diff changeset
723 /* The same as double_int::ext with UNS = true. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 double_int
16
kono
parents: 14
diff changeset
726 double_int::zext (unsigned prec) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 {
16
kono
parents: 14
diff changeset
728 const double_int &cst = *this;
kono
parents: 14
diff changeset
729 double_int mask = double_int::mask (prec);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 double_int r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 r.low = cst.low & mask.low;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 r.high = cst.high & mask.high;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737
16
kono
parents: 14
diff changeset
738 /* The same as double_int::ext with UNS = false. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 double_int
16
kono
parents: 14
diff changeset
741 double_int::sext (unsigned prec) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 {
16
kono
parents: 14
diff changeset
743 const double_int &cst = *this;
kono
parents: 14
diff changeset
744 double_int mask = double_int::mask (prec);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 double_int r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 unsigned HOST_WIDE_INT snum;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 if (prec <= HOST_BITS_PER_WIDE_INT)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 snum = cst.low;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 prec -= HOST_BITS_PER_WIDE_INT;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 snum = (unsigned HOST_WIDE_INT) cst.high;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 if (((snum >> (prec - 1)) & 1) == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 r.low = cst.low | ~mask.low;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758 r.high = cst.high | ~mask.high;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 r.low = cst.low & mask.low;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 r.high = cst.high & mask.high;
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
764 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 /* Returns true if CST fits in signed HOST_WIDE_INT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
770
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771 bool
16
kono
parents: 14
diff changeset
772 double_int::fits_shwi () const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 {
16
kono
parents: 14
diff changeset
774 const double_int &cst = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 if (cst.high == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 return (HOST_WIDE_INT) cst.low >= 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 else if (cst.high == -1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 return (HOST_WIDE_INT) cst.low < 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 /* Returns true if CST fits in HOST_WIDE_INT if UNS is false, or in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 unsigned HOST_WIDE_INT if UNS is true. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 bool
16
kono
parents: 14
diff changeset
787 double_int::fits_hwi (bool uns) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 if (uns)
16
kono
parents: 14
diff changeset
790 return this->fits_uhwi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 else
16
kono
parents: 14
diff changeset
792 return this->fits_shwi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795 /* Returns A * B. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 double_int
16
kono
parents: 14
diff changeset
798 double_int::operator * (double_int b) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 {
16
kono
parents: 14
diff changeset
800 const double_int &a = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
801 double_int ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805
16
kono
parents: 14
diff changeset
806 /* Multiplies *this with B and returns a reference to *this. */
kono
parents: 14
diff changeset
807
kono
parents: 14
diff changeset
808 double_int &
kono
parents: 14
diff changeset
809 double_int::operator *= (double_int b)
kono
parents: 14
diff changeset
810 {
kono
parents: 14
diff changeset
811 mul_double (low, high, b.low, b.high, &low, &high);
kono
parents: 14
diff changeset
812 return *this;
kono
parents: 14
diff changeset
813 }
kono
parents: 14
diff changeset
814
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
815 /* Returns A * B. If the operation overflows according to UNSIGNED_P,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
816 *OVERFLOW is set to nonzero. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
817
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
818 double_int
16
kono
parents: 14
diff changeset
819 double_int::mul_with_sign (double_int b, bool unsigned_p, bool *overflow) const
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
820 {
16
kono
parents: 14
diff changeset
821 const double_int &a = *this;
kono
parents: 14
diff changeset
822 double_int ret, tem;
kono
parents: 14
diff changeset
823 *overflow = mul_double_wide_with_sign (a.low, a.high, b.low, b.high,
kono
parents: 14
diff changeset
824 &ret.low, &ret.high,
kono
parents: 14
diff changeset
825 &tem.low, &tem.high, unsigned_p);
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
826 return ret;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
827 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
828
16
kono
parents: 14
diff changeset
829 double_int
kono
parents: 14
diff changeset
830 double_int::wide_mul_with_sign (double_int b, bool unsigned_p,
kono
parents: 14
diff changeset
831 double_int *higher, bool *overflow) const
kono
parents: 14
diff changeset
832
kono
parents: 14
diff changeset
833 {
kono
parents: 14
diff changeset
834 double_int lower;
kono
parents: 14
diff changeset
835 *overflow = mul_double_wide_with_sign (low, high, b.low, b.high,
kono
parents: 14
diff changeset
836 &lower.low, &lower.high,
kono
parents: 14
diff changeset
837 &higher->low, &higher->high,
kono
parents: 14
diff changeset
838 unsigned_p);
kono
parents: 14
diff changeset
839 return lower;
kono
parents: 14
diff changeset
840 }
kono
parents: 14
diff changeset
841
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 /* Returns A + B. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
844 double_int
16
kono
parents: 14
diff changeset
845 double_int::operator + (double_int b) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
846 {
16
kono
parents: 14
diff changeset
847 const double_int &a = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848 double_int ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
852
16
kono
parents: 14
diff changeset
853 /* Adds B to *this and returns a reference to *this. */
kono
parents: 14
diff changeset
854
kono
parents: 14
diff changeset
855 double_int &
kono
parents: 14
diff changeset
856 double_int::operator += (double_int b)
kono
parents: 14
diff changeset
857 {
kono
parents: 14
diff changeset
858 add_double (low, high, b.low, b.high, &low, &high);
kono
parents: 14
diff changeset
859 return *this;
kono
parents: 14
diff changeset
860 }
kono
parents: 14
diff changeset
861
kono
parents: 14
diff changeset
862
kono
parents: 14
diff changeset
863 /* Returns A + B. If the operation overflows according to UNSIGNED_P,
kono
parents: 14
diff changeset
864 *OVERFLOW is set to nonzero. */
kono
parents: 14
diff changeset
865
kono
parents: 14
diff changeset
866 double_int
kono
parents: 14
diff changeset
867 double_int::add_with_sign (double_int b, bool unsigned_p, bool *overflow) const
kono
parents: 14
diff changeset
868 {
kono
parents: 14
diff changeset
869 const double_int &a = *this;
kono
parents: 14
diff changeset
870 double_int ret;
kono
parents: 14
diff changeset
871 *overflow = add_double_with_sign (a.low, a.high, b.low, b.high,
kono
parents: 14
diff changeset
872 &ret.low, &ret.high, unsigned_p);
kono
parents: 14
diff changeset
873 return ret;
kono
parents: 14
diff changeset
874 }
kono
parents: 14
diff changeset
875
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
876 /* Returns A - B. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
877
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
878 double_int
16
kono
parents: 14
diff changeset
879 double_int::operator - (double_int b) const
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
880 {
16
kono
parents: 14
diff changeset
881 const double_int &a = *this;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
882 double_int ret;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
883 neg_double (b.low, b.high, &b.low, &b.high);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
884 add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
885 return ret;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
886 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
887
16
kono
parents: 14
diff changeset
888 /* Subtracts B from *this and returns a reference to *this. */
kono
parents: 14
diff changeset
889
kono
parents: 14
diff changeset
890 double_int &
kono
parents: 14
diff changeset
891 double_int::operator -= (double_int b)
kono
parents: 14
diff changeset
892 {
kono
parents: 14
diff changeset
893 neg_double (b.low, b.high, &b.low, &b.high);
kono
parents: 14
diff changeset
894 add_double (low, high, b.low, b.high, &low, &high);
kono
parents: 14
diff changeset
895 return *this;
kono
parents: 14
diff changeset
896 }
kono
parents: 14
diff changeset
897
kono
parents: 14
diff changeset
898
kono
parents: 14
diff changeset
899 /* Returns A - B. If the operation overflows via inconsistent sign bits,
kono
parents: 14
diff changeset
900 *OVERFLOW is set to nonzero. */
kono
parents: 14
diff changeset
901
kono
parents: 14
diff changeset
902 double_int
kono
parents: 14
diff changeset
903 double_int::sub_with_overflow (double_int b, bool *overflow) const
kono
parents: 14
diff changeset
904 {
kono
parents: 14
diff changeset
905 double_int ret;
kono
parents: 14
diff changeset
906 neg_double (b.low, b.high, &ret.low, &ret.high);
kono
parents: 14
diff changeset
907 add_double (low, high, ret.low, ret.high, &ret.low, &ret.high);
kono
parents: 14
diff changeset
908 *overflow = OVERFLOW_SUM_SIGN (ret.high, b.high, high);
kono
parents: 14
diff changeset
909 return ret;
kono
parents: 14
diff changeset
910 }
kono
parents: 14
diff changeset
911
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 /* Returns -A. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 double_int
16
kono
parents: 14
diff changeset
915 double_int::operator - () const
kono
parents: 14
diff changeset
916 {
kono
parents: 14
diff changeset
917 const double_int &a = *this;
kono
parents: 14
diff changeset
918 double_int ret;
kono
parents: 14
diff changeset
919 neg_double (a.low, a.high, &ret.low, &ret.high);
kono
parents: 14
diff changeset
920 return ret;
kono
parents: 14
diff changeset
921 }
kono
parents: 14
diff changeset
922
kono
parents: 14
diff changeset
923 double_int
kono
parents: 14
diff changeset
924 double_int::neg_with_overflow (bool *overflow) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 double_int ret;
16
kono
parents: 14
diff changeset
927 *overflow = neg_double (low, high, &ret.low, &ret.high);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 /* Returns A / B (computed as unsigned depending on UNS, and rounded as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 specified by CODE). CODE is enum tree_code in fact, but double_int.h
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 must be included before tree.h. The remainder after the division is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 stored to MOD. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936 double_int
16
kono
parents: 14
diff changeset
937 double_int::divmod_with_overflow (double_int b, bool uns, unsigned code,
kono
parents: 14
diff changeset
938 double_int *mod, bool *overflow) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 {
16
kono
parents: 14
diff changeset
940 const double_int &a = *this;
kono
parents: 14
diff changeset
941 double_int ret;
kono
parents: 14
diff changeset
942
kono
parents: 14
diff changeset
943 *overflow = div_and_round_double (code, uns, a.low, a.high,
kono
parents: 14
diff changeset
944 b.low, b.high, &ret.low, &ret.high,
kono
parents: 14
diff changeset
945 &mod->low, &mod->high);
kono
parents: 14
diff changeset
946 return ret;
kono
parents: 14
diff changeset
947 }
kono
parents: 14
diff changeset
948
kono
parents: 14
diff changeset
949 double_int
kono
parents: 14
diff changeset
950 double_int::divmod (double_int b, bool uns, unsigned code,
kono
parents: 14
diff changeset
951 double_int *mod) const
kono
parents: 14
diff changeset
952 {
kono
parents: 14
diff changeset
953 const double_int &a = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 double_int ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
956 div_and_round_double (code, uns, a.low, a.high,
9
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
957 b.low, b.high, &ret.low, &ret.high,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
958 &mod->low, &mod->high);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 return ret;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961
16
kono
parents: 14
diff changeset
962 /* The same as double_int::divmod with UNS = false. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 double_int
16
kono
parents: 14
diff changeset
965 double_int::sdivmod (double_int b, unsigned code, double_int *mod) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 {
16
kono
parents: 14
diff changeset
967 return this->divmod (b, false, code, mod);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969
16
kono
parents: 14
diff changeset
970 /* The same as double_int::divmod with UNS = true. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 double_int
16
kono
parents: 14
diff changeset
973 double_int::udivmod (double_int b, unsigned code, double_int *mod) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 {
16
kono
parents: 14
diff changeset
975 return this->divmod (b, true, code, mod);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 /* Returns A / B (computed as unsigned depending on UNS, and rounded as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
979 specified by CODE). CODE is enum tree_code in fact, but double_int.h
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 must be included before tree.h. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 double_int
16
kono
parents: 14
diff changeset
983 double_int::div (double_int b, bool uns, unsigned code) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985 double_int mod;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986
16
kono
parents: 14
diff changeset
987 return this->divmod (b, uns, code, &mod);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989
16
kono
parents: 14
diff changeset
990 /* The same as double_int::div with UNS = false. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 double_int
16
kono
parents: 14
diff changeset
993 double_int::sdiv (double_int b, unsigned code) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 {
16
kono
parents: 14
diff changeset
995 return this->div (b, false, code);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997
16
kono
parents: 14
diff changeset
998 /* The same as double_int::div with UNS = true. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 double_int
16
kono
parents: 14
diff changeset
1001 double_int::udiv (double_int b, unsigned code) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 {
16
kono
parents: 14
diff changeset
1003 return this->div (b, true, code);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006 /* Returns A % B (computed as unsigned depending on UNS, and rounded as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 specified by CODE). CODE is enum tree_code in fact, but double_int.h
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 must be included before tree.h. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010 double_int
16
kono
parents: 14
diff changeset
1011 double_int::mod (double_int b, bool uns, unsigned code) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1012 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 double_int mod;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014
16
kono
parents: 14
diff changeset
1015 this->divmod (b, uns, code, &mod);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 return mod;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018
16
kono
parents: 14
diff changeset
1019 /* The same as double_int::mod with UNS = false. */
kono
parents: 14
diff changeset
1020
kono
parents: 14
diff changeset
1021 double_int
kono
parents: 14
diff changeset
1022 double_int::smod (double_int b, unsigned code) const
kono
parents: 14
diff changeset
1023 {
kono
parents: 14
diff changeset
1024 return this->mod (b, false, code);
kono
parents: 14
diff changeset
1025 }
kono
parents: 14
diff changeset
1026
kono
parents: 14
diff changeset
1027 /* The same as double_int::mod with UNS = true. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1028
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1029 double_int
16
kono
parents: 14
diff changeset
1030 double_int::umod (double_int b, unsigned code) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031 {
16
kono
parents: 14
diff changeset
1032 return this->mod (b, true, code);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034
16
kono
parents: 14
diff changeset
1035 /* Return TRUE iff PRODUCT is an integral multiple of FACTOR, and return
kono
parents: 14
diff changeset
1036 the multiple in *MULTIPLE. Otherwise return FALSE and leave *MULTIPLE
kono
parents: 14
diff changeset
1037 unchanged. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038
16
kono
parents: 14
diff changeset
1039 bool
kono
parents: 14
diff changeset
1040 double_int::multiple_of (double_int factor,
kono
parents: 14
diff changeset
1041 bool unsigned_p, double_int *multiple) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042 {
16
kono
parents: 14
diff changeset
1043 double_int remainder;
kono
parents: 14
diff changeset
1044 double_int quotient = this->divmod (factor, unsigned_p,
kono
parents: 14
diff changeset
1045 TRUNC_DIV_EXPR, &remainder);
kono
parents: 14
diff changeset
1046 if (remainder.is_zero ())
kono
parents: 14
diff changeset
1047 {
kono
parents: 14
diff changeset
1048 *multiple = quotient;
kono
parents: 14
diff changeset
1049 return true;
kono
parents: 14
diff changeset
1050 }
kono
parents: 14
diff changeset
1051
kono
parents: 14
diff changeset
1052 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1053 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1054
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1055 /* Set BITPOS bit in A. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1056 double_int
16
kono
parents: 14
diff changeset
1057 double_int::set_bit (unsigned bitpos) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 {
16
kono
parents: 14
diff changeset
1059 double_int a = *this;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1060 if (bitpos < HOST_BITS_PER_WIDE_INT)
16
kono
parents: 14
diff changeset
1061 a.low |= HOST_WIDE_INT_1U << bitpos;
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1062 else
16
kono
parents: 14
diff changeset
1063 a.high |= HOST_WIDE_INT_1 << (bitpos - HOST_BITS_PER_WIDE_INT);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1064
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1065 return a;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1068 /* Count trailing zeros in A. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1069 int
16
kono
parents: 14
diff changeset
1070 double_int::trailing_zeros () const
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1071 {
16
kono
parents: 14
diff changeset
1072 const double_int &a = *this;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1073 unsigned HOST_WIDE_INT w = a.low ? a.low : (unsigned HOST_WIDE_INT) a.high;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1074 unsigned bits = a.low ? 0 : HOST_BITS_PER_WIDE_INT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1075 if (!w)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1076 return HOST_BITS_PER_DOUBLE_INT;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1077 bits += ctz_hwi (w);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1078 return bits;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1079 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1080
16
kono
parents: 14
diff changeset
1081 /* Shift A left by COUNT places. */
kono
parents: 14
diff changeset
1082
kono
parents: 14
diff changeset
1083 double_int
kono
parents: 14
diff changeset
1084 double_int::lshift (HOST_WIDE_INT count) const
kono
parents: 14
diff changeset
1085 {
kono
parents: 14
diff changeset
1086 double_int ret;
kono
parents: 14
diff changeset
1087
kono
parents: 14
diff changeset
1088 gcc_checking_assert (count >= 0);
kono
parents: 14
diff changeset
1089
kono
parents: 14
diff changeset
1090 if (count >= HOST_BITS_PER_DOUBLE_INT)
kono
parents: 14
diff changeset
1091 {
kono
parents: 14
diff changeset
1092 /* Shifting by the host word size is undefined according to the
kono
parents: 14
diff changeset
1093 ANSI standard, so we must handle this as a special case. */
kono
parents: 14
diff changeset
1094 ret.high = 0;
kono
parents: 14
diff changeset
1095 ret.low = 0;
kono
parents: 14
diff changeset
1096 }
kono
parents: 14
diff changeset
1097 else if (count >= HOST_BITS_PER_WIDE_INT)
kono
parents: 14
diff changeset
1098 {
kono
parents: 14
diff changeset
1099 ret.high = low << (count - HOST_BITS_PER_WIDE_INT);
kono
parents: 14
diff changeset
1100 ret.low = 0;
kono
parents: 14
diff changeset
1101 }
kono
parents: 14
diff changeset
1102 else
kono
parents: 14
diff changeset
1103 {
kono
parents: 14
diff changeset
1104 ret.high = (((unsigned HOST_WIDE_INT) high << count)
kono
parents: 14
diff changeset
1105 | (low >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
kono
parents: 14
diff changeset
1106 ret.low = low << count;
kono
parents: 14
diff changeset
1107 }
kono
parents: 14
diff changeset
1108
kono
parents: 14
diff changeset
1109 return ret;
kono
parents: 14
diff changeset
1110 }
kono
parents: 14
diff changeset
1111
kono
parents: 14
diff changeset
1112 /* Shift A right by COUNT places. */
kono
parents: 14
diff changeset
1113
kono
parents: 14
diff changeset
1114 double_int
kono
parents: 14
diff changeset
1115 double_int::rshift (HOST_WIDE_INT count) const
kono
parents: 14
diff changeset
1116 {
kono
parents: 14
diff changeset
1117 double_int ret;
kono
parents: 14
diff changeset
1118
kono
parents: 14
diff changeset
1119 gcc_checking_assert (count >= 0);
kono
parents: 14
diff changeset
1120
kono
parents: 14
diff changeset
1121 if (count >= HOST_BITS_PER_DOUBLE_INT)
kono
parents: 14
diff changeset
1122 {
kono
parents: 14
diff changeset
1123 /* Shifting by the host word size is undefined according to the
kono
parents: 14
diff changeset
1124 ANSI standard, so we must handle this as a special case. */
kono
parents: 14
diff changeset
1125 ret.high = 0;
kono
parents: 14
diff changeset
1126 ret.low = 0;
kono
parents: 14
diff changeset
1127 }
kono
parents: 14
diff changeset
1128 else if (count >= HOST_BITS_PER_WIDE_INT)
kono
parents: 14
diff changeset
1129 {
kono
parents: 14
diff changeset
1130 ret.high = 0;
kono
parents: 14
diff changeset
1131 ret.low
kono
parents: 14
diff changeset
1132 = (unsigned HOST_WIDE_INT) (high >> (count - HOST_BITS_PER_WIDE_INT));
kono
parents: 14
diff changeset
1133 }
kono
parents: 14
diff changeset
1134 else
kono
parents: 14
diff changeset
1135 {
kono
parents: 14
diff changeset
1136 ret.high = high >> count;
kono
parents: 14
diff changeset
1137 ret.low = ((low >> count)
kono
parents: 14
diff changeset
1138 | ((unsigned HOST_WIDE_INT) high
kono
parents: 14
diff changeset
1139 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
kono
parents: 14
diff changeset
1140 }
kono
parents: 14
diff changeset
1141
kono
parents: 14
diff changeset
1142 return ret;
kono
parents: 14
diff changeset
1143 }
kono
parents: 14
diff changeset
1144
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1145 /* Shift A left by COUNT places keeping only PREC bits of result. Shift
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1146 right if COUNT is negative. ARITH true specifies arithmetic shifting;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1147 otherwise use logical shift. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1149 double_int
16
kono
parents: 14
diff changeset
1150 double_int::lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 {
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1152 double_int ret;
16
kono
parents: 14
diff changeset
1153 if (count > 0)
kono
parents: 14
diff changeset
1154 lshift_double (low, high, count, prec, &ret.low, &ret.high);
kono
parents: 14
diff changeset
1155 else
kono
parents: 14
diff changeset
1156 rshift_double (low, high, absu_hwi (count), prec, &ret.low, &ret.high, arith);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1157 return ret;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1159
16
kono
parents: 14
diff changeset
1160 /* Shift A right by COUNT places keeping only PREC bits of result. Shift
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1161 left if COUNT is negative. ARITH true specifies arithmetic shifting;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1162 otherwise use logical shift. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1164 double_int
16
kono
parents: 14
diff changeset
1165 double_int::rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 {
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1167 double_int ret;
16
kono
parents: 14
diff changeset
1168 if (count > 0)
kono
parents: 14
diff changeset
1169 rshift_double (low, high, count, prec, &ret.low, &ret.high, arith);
kono
parents: 14
diff changeset
1170 else
kono
parents: 14
diff changeset
1171 lshift_double (low, high, absu_hwi (count), prec, &ret.low, &ret.high);
11
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 9
diff changeset
1172 return ret;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174
16
kono
parents: 14
diff changeset
1175 /* Arithmetic shift A left by COUNT places keeping only PREC bits of result.
kono
parents: 14
diff changeset
1176 Shift right if COUNT is negative. */
kono
parents: 14
diff changeset
1177
kono
parents: 14
diff changeset
1178 double_int
kono
parents: 14
diff changeset
1179 double_int::alshift (HOST_WIDE_INT count, unsigned int prec) const
kono
parents: 14
diff changeset
1180 {
kono
parents: 14
diff changeset
1181 double_int r;
kono
parents: 14
diff changeset
1182 if (count > 0)
kono
parents: 14
diff changeset
1183 lshift_double (low, high, count, prec, &r.low, &r.high);
kono
parents: 14
diff changeset
1184 else
kono
parents: 14
diff changeset
1185 rshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high, true);
kono
parents: 14
diff changeset
1186 return r;
kono
parents: 14
diff changeset
1187 }
kono
parents: 14
diff changeset
1188
kono
parents: 14
diff changeset
1189 /* Arithmetic shift A right by COUNT places keeping only PREC bits of result.
kono
parents: 14
diff changeset
1190 Shift left if COUNT is negative. */
kono
parents: 14
diff changeset
1191
kono
parents: 14
diff changeset
1192 double_int
kono
parents: 14
diff changeset
1193 double_int::arshift (HOST_WIDE_INT count, unsigned int prec) const
kono
parents: 14
diff changeset
1194 {
kono
parents: 14
diff changeset
1195 double_int r;
kono
parents: 14
diff changeset
1196 if (count > 0)
kono
parents: 14
diff changeset
1197 rshift_double (low, high, count, prec, &r.low, &r.high, true);
kono
parents: 14
diff changeset
1198 else
kono
parents: 14
diff changeset
1199 lshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high);
kono
parents: 14
diff changeset
1200 return r;
kono
parents: 14
diff changeset
1201 }
kono
parents: 14
diff changeset
1202
kono
parents: 14
diff changeset
1203 /* Logical shift A left by COUNT places keeping only PREC bits of result.
kono
parents: 14
diff changeset
1204 Shift right if COUNT is negative. */
kono
parents: 14
diff changeset
1205
kono
parents: 14
diff changeset
1206 double_int
kono
parents: 14
diff changeset
1207 double_int::llshift (HOST_WIDE_INT count, unsigned int prec) const
kono
parents: 14
diff changeset
1208 {
kono
parents: 14
diff changeset
1209 double_int r;
kono
parents: 14
diff changeset
1210 if (count > 0)
kono
parents: 14
diff changeset
1211 lshift_double (low, high, count, prec, &r.low, &r.high);
kono
parents: 14
diff changeset
1212 else
kono
parents: 14
diff changeset
1213 rshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high, false);
kono
parents: 14
diff changeset
1214 return r;
kono
parents: 14
diff changeset
1215 }
kono
parents: 14
diff changeset
1216
kono
parents: 14
diff changeset
1217 /* Logical shift A right by COUNT places keeping only PREC bits of result.
kono
parents: 14
diff changeset
1218 Shift left if COUNT is negative. */
kono
parents: 14
diff changeset
1219
kono
parents: 14
diff changeset
1220 double_int
kono
parents: 14
diff changeset
1221 double_int::lrshift (HOST_WIDE_INT count, unsigned int prec) const
kono
parents: 14
diff changeset
1222 {
kono
parents: 14
diff changeset
1223 double_int r;
kono
parents: 14
diff changeset
1224 if (count > 0)
kono
parents: 14
diff changeset
1225 rshift_double (low, high, count, prec, &r.low, &r.high, false);
kono
parents: 14
diff changeset
1226 else
kono
parents: 14
diff changeset
1227 lshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high);
kono
parents: 14
diff changeset
1228 return r;
kono
parents: 14
diff changeset
1229 }
kono
parents: 14
diff changeset
1230
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1231 /* Rotate A left by COUNT places keeping only PREC bits of result.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1232 Rotate right if COUNT is negative. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1233
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1234 double_int
16
kono
parents: 14
diff changeset
1235 double_int::lrotate (HOST_WIDE_INT count, unsigned int prec) const
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1236 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1237 double_int t1, t2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1238
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1239 count %= prec;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1240 if (count < 0)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1241 count += prec;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1242
16
kono
parents: 14
diff changeset
1243 t1 = this->llshift (count, prec);
kono
parents: 14
diff changeset
1244 t2 = this->lrshift (prec - count, prec);
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1245
16
kono
parents: 14
diff changeset
1246 return t1 | t2;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1247 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1248
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1249 /* Rotate A rigth by COUNT places keeping only PREC bits of result.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1250 Rotate right if COUNT is negative. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1251
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1252 double_int
16
kono
parents: 14
diff changeset
1253 double_int::rrotate (HOST_WIDE_INT count, unsigned int prec) const
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1254 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1255 double_int t1, t2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1256
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1257 count %= prec;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1258 if (count < 0)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1259 count += prec;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1260
16
kono
parents: 14
diff changeset
1261 t1 = this->lrshift (count, prec);
kono
parents: 14
diff changeset
1262 t2 = this->llshift (prec - count, prec);
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1263
16
kono
parents: 14
diff changeset
1264 return t1 | t2;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1265 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1266
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267 /* Returns -1 if A < B, 0 if A == B and 1 if A > B. Signedness of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 comparison is given by UNS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270 int
16
kono
parents: 14
diff changeset
1271 double_int::cmp (double_int b, bool uns) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273 if (uns)
16
kono
parents: 14
diff changeset
1274 return this->ucmp (b);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275 else
16
kono
parents: 14
diff changeset
1276 return this->scmp (b);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 /* Compares two unsigned values A and B. Returns -1 if A < B, 0 if A == B,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280 and 1 if A > B. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 int
16
kono
parents: 14
diff changeset
1283 double_int::ucmp (double_int b) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284 {
16
kono
parents: 14
diff changeset
1285 const double_int &a = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1286 if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288 if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 if (a.low < b.low)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292 if (a.low > b.low)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1296 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1298 /* Compares two signed values A and B. Returns -1 if A < B, 0 if A == B,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 and 1 if A > B. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 int
16
kono
parents: 14
diff changeset
1302 double_int::scmp (double_int b) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303 {
16
kono
parents: 14
diff changeset
1304 const double_int &a = *this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 if (a.high < b.high)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307 if (a.high > b.high)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 if (a.low < b.low)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 return -1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311 if (a.low > b.low)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1316
16
kono
parents: 14
diff changeset
1317 /* Compares two unsigned values A and B for less-than. */
kono
parents: 14
diff changeset
1318
kono
parents: 14
diff changeset
1319 bool
kono
parents: 14
diff changeset
1320 double_int::ult (double_int b) const
kono
parents: 14
diff changeset
1321 {
kono
parents: 14
diff changeset
1322 if ((unsigned HOST_WIDE_INT) high < (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1323 return true;
kono
parents: 14
diff changeset
1324 if ((unsigned HOST_WIDE_INT) high > (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1325 return false;
kono
parents: 14
diff changeset
1326 if (low < b.low)
kono
parents: 14
diff changeset
1327 return true;
kono
parents: 14
diff changeset
1328 return false;
kono
parents: 14
diff changeset
1329 }
kono
parents: 14
diff changeset
1330
kono
parents: 14
diff changeset
1331 /* Compares two unsigned values A and B for less-than or equal-to. */
kono
parents: 14
diff changeset
1332
kono
parents: 14
diff changeset
1333 bool
kono
parents: 14
diff changeset
1334 double_int::ule (double_int b) const
kono
parents: 14
diff changeset
1335 {
kono
parents: 14
diff changeset
1336 if ((unsigned HOST_WIDE_INT) high < (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1337 return true;
kono
parents: 14
diff changeset
1338 if ((unsigned HOST_WIDE_INT) high > (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1339 return false;
kono
parents: 14
diff changeset
1340 if (low <= b.low)
kono
parents: 14
diff changeset
1341 return true;
kono
parents: 14
diff changeset
1342 return false;
kono
parents: 14
diff changeset
1343 }
kono
parents: 14
diff changeset
1344
kono
parents: 14
diff changeset
1345 /* Compares two unsigned values A and B for greater-than. */
kono
parents: 14
diff changeset
1346
kono
parents: 14
diff changeset
1347 bool
kono
parents: 14
diff changeset
1348 double_int::ugt (double_int b) const
kono
parents: 14
diff changeset
1349 {
kono
parents: 14
diff changeset
1350 if ((unsigned HOST_WIDE_INT) high > (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1351 return true;
kono
parents: 14
diff changeset
1352 if ((unsigned HOST_WIDE_INT) high < (unsigned HOST_WIDE_INT) b.high)
kono
parents: 14
diff changeset
1353 return false;
kono
parents: 14
diff changeset
1354 if (low > b.low)
kono
parents: 14
diff changeset
1355 return true;
kono
parents: 14
diff changeset
1356 return false;
kono
parents: 14
diff changeset
1357 }
kono
parents: 14
diff changeset
1358
kono
parents: 14
diff changeset
1359 /* Compares two signed values A and B for less-than. */
kono
parents: 14
diff changeset
1360
kono
parents: 14
diff changeset
1361 bool
kono
parents: 14
diff changeset
1362 double_int::slt (double_int b) const
kono
parents: 14
diff changeset
1363 {
kono
parents: 14
diff changeset
1364 if (high < b.high)
kono
parents: 14
diff changeset
1365 return true;
kono
parents: 14
diff changeset
1366 if (high > b.high)
kono
parents: 14
diff changeset
1367 return false;
kono
parents: 14
diff changeset
1368 if (low < b.low)
kono
parents: 14
diff changeset
1369 return true;
kono
parents: 14
diff changeset
1370 return false;
kono
parents: 14
diff changeset
1371 }
kono
parents: 14
diff changeset
1372
kono
parents: 14
diff changeset
1373 /* Compares two signed values A and B for less-than or equal-to. */
kono
parents: 14
diff changeset
1374
kono
parents: 14
diff changeset
1375 bool
kono
parents: 14
diff changeset
1376 double_int::sle (double_int b) const
kono
parents: 14
diff changeset
1377 {
kono
parents: 14
diff changeset
1378 if (high < b.high)
kono
parents: 14
diff changeset
1379 return true;
kono
parents: 14
diff changeset
1380 if (high > b.high)
kono
parents: 14
diff changeset
1381 return false;
kono
parents: 14
diff changeset
1382 if (low <= b.low)
kono
parents: 14
diff changeset
1383 return true;
kono
parents: 14
diff changeset
1384 return false;
kono
parents: 14
diff changeset
1385 }
kono
parents: 14
diff changeset
1386
kono
parents: 14
diff changeset
1387 /* Compares two signed values A and B for greater-than. */
kono
parents: 14
diff changeset
1388
kono
parents: 14
diff changeset
1389 bool
kono
parents: 14
diff changeset
1390 double_int::sgt (double_int b) const
kono
parents: 14
diff changeset
1391 {
kono
parents: 14
diff changeset
1392 if (high > b.high)
kono
parents: 14
diff changeset
1393 return true;
kono
parents: 14
diff changeset
1394 if (high < b.high)
kono
parents: 14
diff changeset
1395 return false;
kono
parents: 14
diff changeset
1396 if (low > b.low)
kono
parents: 14
diff changeset
1397 return true;
kono
parents: 14
diff changeset
1398 return false;
kono
parents: 14
diff changeset
1399 }
kono
parents: 14
diff changeset
1400
kono
parents: 14
diff changeset
1401
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1402 /* Compares two values A and B. Returns max value. Signedness of the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1403 comparison is given by UNS. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1404
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1405 double_int
16
kono
parents: 14
diff changeset
1406 double_int::max (double_int b, bool uns)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1407 {
16
kono
parents: 14
diff changeset
1408 return (this->cmp (b, uns) == 1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1409 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1410
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1411 /* Compares two signed values A and B. Returns max value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1412
16
kono
parents: 14
diff changeset
1413 double_int
kono
parents: 14
diff changeset
1414 double_int::smax (double_int b)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1415 {
16
kono
parents: 14
diff changeset
1416 return (this->scmp (b) == 1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1417 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1418
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1419 /* Compares two unsigned values A and B. Returns max value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1420
16
kono
parents: 14
diff changeset
1421 double_int
kono
parents: 14
diff changeset
1422 double_int::umax (double_int b)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1423 {
16
kono
parents: 14
diff changeset
1424 return (this->ucmp (b) == 1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1425 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1426
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1427 /* Compares two values A and B. Returns mix value. Signedness of the
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1428 comparison is given by UNS. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1429
16
kono
parents: 14
diff changeset
1430 double_int
kono
parents: 14
diff changeset
1431 double_int::min (double_int b, bool uns)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1432 {
16
kono
parents: 14
diff changeset
1433 return (this->cmp (b, uns) == -1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1434 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1435
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1436 /* Compares two signed values A and B. Returns min value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1437
16
kono
parents: 14
diff changeset
1438 double_int
kono
parents: 14
diff changeset
1439 double_int::smin (double_int b)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1440 {
16
kono
parents: 14
diff changeset
1441 return (this->scmp (b) == -1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1442 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1443
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1444 /* Compares two unsigned values A and B. Returns min value. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1445
16
kono
parents: 14
diff changeset
1446 double_int
kono
parents: 14
diff changeset
1447 double_int::umin (double_int b)
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1448 {
16
kono
parents: 14
diff changeset
1449 return (this->ucmp (b) == -1) ? *this : b;
14
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1450 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 11
diff changeset
1451
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 /* Splits last digit of *CST (taken as unsigned) in BASE and returns it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 static unsigned
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455 double_int_split_digit (double_int *cst, unsigned base)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 unsigned HOST_WIDE_INT resl, reml;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458 HOST_WIDE_INT resh, remh;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 &resl, &resh, &reml, &remh);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 cst->high = resh;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 cst->low = resl;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 return reml;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 /* Dumps CST to FILE. If UNS is true, CST is considered to be unsigned,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 otherwise it is signed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 dump_double_int (FILE *file, double_int cst, bool uns)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1473 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 unsigned digits[100], n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1476
16
kono
parents: 14
diff changeset
1477 if (cst.is_zero ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 fprintf (file, "0");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482
16
kono
parents: 14
diff changeset
1483 if (!uns && cst.is_negative ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 fprintf (file, "-");
16
kono
parents: 14
diff changeset
1486 cst = -cst;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488
16
kono
parents: