annotate gcc/sreal.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents: 67
diff changeset
1 /* Simple data type for real numbers for the GNU compiler.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
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 under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
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 ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 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.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
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
111
kono
parents: 67
diff changeset
20 /* This library supports real numbers;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 inf and nan are NOT supported.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 It is written to be simple and fast.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 Value of sreal is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 x = sig * 2 ^ exp
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 where
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 sig = significant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 (for < 64-bit machines sig = sig_lo + sig_hi * 2 ^ SREAL_PART_BITS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 exp = exponent
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
111
kono
parents: 67
diff changeset
31 One uint64_t is used for the significant.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 Only a half of significant bits is used (in normalized sreals) so that we do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 not have problems with overflow, for example when c->sig = a->sig * b->sig.
111
kono
parents: 67
diff changeset
34 So the precision is 32-bit.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 Invariant: The numbers are normalized before and after each call of sreal_*.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 Normalized sreals:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 All numbers (except zero) meet following conditions:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 SREAL_MIN_SIG <= sig && sig <= SREAL_MAX_SIG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 -SREAL_MAX_EXP <= exp && exp <= SREAL_MAX_EXP
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 If the number would be too large, it is set to upper bounds of these
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 conditions.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 If the number is zero or would be too small it meets following conditions:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 sig == 0 && exp == -SREAL_MAX_EXP
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 #include "system.h"
111
kono
parents: 67
diff changeset
52 #include <math.h>
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 #include "coretypes.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 #include "sreal.h"
111
kono
parents: 67
diff changeset
55 #include "selftest.h"
kono
parents: 67
diff changeset
56 #include "backend.h"
kono
parents: 67
diff changeset
57 #include "tree.h"
kono
parents: 67
diff changeset
58 #include "gimple.h"
kono
parents: 67
diff changeset
59 #include "cgraph.h"
kono
parents: 67
diff changeset
60 #include "data-streamer.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 /* Print the content of struct sreal. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 void
111
kono
parents: 67
diff changeset
65 sreal::dump (FILE *file) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 fprintf (file, "(%" PRIi64 " * 2^%d)", (int64_t)m_sig, m_exp);
111
kono
parents: 67
diff changeset
68 }
kono
parents: 67
diff changeset
69
kono
parents: 67
diff changeset
70 DEBUG_FUNCTION void
kono
parents: 67
diff changeset
71 debug (const sreal &ref)
kono
parents: 67
diff changeset
72 {
kono
parents: 67
diff changeset
73 ref.dump (stderr);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
111
kono
parents: 67
diff changeset
76 DEBUG_FUNCTION void
kono
parents: 67
diff changeset
77 debug (const sreal *ptr)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 {
111
kono
parents: 67
diff changeset
79 if (ptr)
kono
parents: 67
diff changeset
80 debug (*ptr);
kono
parents: 67
diff changeset
81 else
kono
parents: 67
diff changeset
82 fprintf (stderr, "<nil>\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
111
kono
parents: 67
diff changeset
85 /* Shift this right by S bits. Needed: 0 < S <= SREAL_BITS.
kono
parents: 67
diff changeset
86 When the most significant bit shifted out is 1, add 1 to this (rounding).
kono
parents: 67
diff changeset
87 */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
111
kono
parents: 67
diff changeset
89 void
kono
parents: 67
diff changeset
90 sreal::shift_right (int s)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 {
111
kono
parents: 67
diff changeset
92 gcc_checking_assert (s > 0);
kono
parents: 67
diff changeset
93 gcc_checking_assert (s <= SREAL_BITS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 /* Exponent should never be so large because shift_right is used only by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 sreal_add and sreal_sub ant thus the number cannot be shifted out from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 exponent range. */
111
kono
parents: 67
diff changeset
97 gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
kono
parents: 67
diff changeset
98
kono
parents: 67
diff changeset
99 m_exp += s;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
111
kono
parents: 67
diff changeset
101 m_sig += (int64_t) 1 << (s - 1);
kono
parents: 67
diff changeset
102 m_sig >>= s;
kono
parents: 67
diff changeset
103 }
kono
parents: 67
diff changeset
104
kono
parents: 67
diff changeset
105 /* Return integer value of *this. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106
111
kono
parents: 67
diff changeset
107 int64_t
kono
parents: 67
diff changeset
108 sreal::to_int () const
kono
parents: 67
diff changeset
109 {
kono
parents: 67
diff changeset
110 int64_t sign = SREAL_SIGN (m_sig);
kono
parents: 67
diff changeset
111
kono
parents: 67
diff changeset
112 if (m_exp <= -SREAL_BITS)
kono
parents: 67
diff changeset
113 return 0;
kono
parents: 67
diff changeset
114 if (m_exp >= SREAL_PART_BITS)
kono
parents: 67
diff changeset
115 return sign * INTTYPE_MAXIMUM (int64_t);
kono
parents: 67
diff changeset
116 if (m_exp > 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 return sign * (SREAL_ABS ((int64_t)m_sig) << m_exp);
111
kono
parents: 67
diff changeset
118 if (m_exp < 0)
kono
parents: 67
diff changeset
119 return m_sig >> -m_exp;
kono
parents: 67
diff changeset
120 return m_sig;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
111
kono
parents: 67
diff changeset
123 /* Return value of *this as double.
kono
parents: 67
diff changeset
124 This should be used for debug output only. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
111
kono
parents: 67
diff changeset
126 double
kono
parents: 67
diff changeset
127 sreal::to_double () const
kono
parents: 67
diff changeset
128 {
kono
parents: 67
diff changeset
129 double val = m_sig;
kono
parents: 67
diff changeset
130 if (m_exp)
kono
parents: 67
diff changeset
131 val = ldexp (val, m_exp);
kono
parents: 67
diff changeset
132 return val;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
111
kono
parents: 67
diff changeset
135 /* Return *this + other. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136
111
kono
parents: 67
diff changeset
137 sreal
kono
parents: 67
diff changeset
138 sreal::operator+ (const sreal &other) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 int dexp;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 sreal tmp;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142 int64_t r_sig, r_exp;
111
kono
parents: 67
diff changeset
143
kono
parents: 67
diff changeset
144 const sreal *a_p = this, *b_p = &other, *bb;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145
111
kono
parents: 67
diff changeset
146 if (a_p->m_exp < b_p->m_exp)
kono
parents: 67
diff changeset
147 std::swap (a_p, b_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148
111
kono
parents: 67
diff changeset
149 dexp = a_p->m_exp - b_p->m_exp;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 r_exp = a_p->m_exp;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 if (dexp > SREAL_BITS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 r_sig = a_p->m_sig;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 sreal r;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 r.m_sig = r_sig;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 r.m_exp = r_exp;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 if (dexp == 0)
111
kono
parents: 67
diff changeset
162 bb = b_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 {
111
kono
parents: 67
diff changeset
165 tmp = *b_p;
kono
parents: 67
diff changeset
166 tmp.shift_right (dexp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 bb = &tmp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 r_sig = a_p->m_sig + (int64_t)bb->m_sig;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 sreal r (r_sig, r_exp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174
111
kono
parents: 67
diff changeset
175
kono
parents: 67
diff changeset
176 /* Return *this - other. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
111
kono
parents: 67
diff changeset
178 sreal
kono
parents: 67
diff changeset
179 sreal::operator- (const sreal &other) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 int dexp;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 sreal tmp;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 int64_t r_sig, r_exp;
111
kono
parents: 67
diff changeset
184 const sreal *bb;
kono
parents: 67
diff changeset
185 const sreal *a_p = this, *b_p = &other;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186
111
kono
parents: 67
diff changeset
187 int64_t sign = 1;
kono
parents: 67
diff changeset
188 if (a_p->m_exp < b_p->m_exp)
kono
parents: 67
diff changeset
189 {
kono
parents: 67
diff changeset
190 sign = -1;
kono
parents: 67
diff changeset
191 std::swap (a_p, b_p);
kono
parents: 67
diff changeset
192 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
111
kono
parents: 67
diff changeset
194 dexp = a_p->m_exp - b_p->m_exp;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 r_exp = a_p->m_exp;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 if (dexp > SREAL_BITS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 r_sig = sign * a_p->m_sig;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 sreal r;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
201 r.m_sig = r_sig;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
202 r.m_exp = r_exp;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 if (dexp == 0)
111
kono
parents: 67
diff changeset
206 bb = b_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 {
111
kono
parents: 67
diff changeset
209 tmp = *b_p;
kono
parents: 67
diff changeset
210 tmp.shift_right (dexp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 bb = &tmp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 r_sig = sign * ((int64_t) a_p->m_sig - (int64_t)bb->m_sig);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
215 sreal r (r_sig, r_exp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218
111
kono
parents: 67
diff changeset
219 /* Return *this * other. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220
111
kono
parents: 67
diff changeset
221 sreal
kono
parents: 67
diff changeset
222 sreal::operator* (const sreal &other) const
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 {
111
kono
parents: 67
diff changeset
224 sreal r;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225 if (absu_hwi (m_sig) < SREAL_MIN_SIG
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 || absu_hwi (other.m_sig) < SREAL_MIN_SIG)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 {
111
kono
parents: 67
diff changeset
228 r.m_sig = 0;
kono
parents: 67
diff changeset
229 r.m_exp = -SREAL_MAX_EXP;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 r.normalize (m_sig * (int64_t) other.m_sig, m_exp + other.m_exp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233
111
kono
parents: 67
diff changeset
234 return r;
kono
parents: 67
diff changeset
235 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
111
kono
parents: 67
diff changeset
237 /* Return *this / other. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238
111
kono
parents: 67
diff changeset
239 sreal
kono
parents: 67
diff changeset
240 sreal::operator/ (const sreal &other) const
kono
parents: 67
diff changeset
241 {
kono
parents: 67
diff changeset
242 gcc_checking_assert (other.m_sig != 0);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 sreal r (SREAL_SIGN (m_sig)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 * ((int64_t)SREAL_ABS (m_sig) << SREAL_PART_BITS) / other.m_sig,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 m_exp - other.m_exp - SREAL_PART_BITS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 return r;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
111
kono
parents: 67
diff changeset
249 /* Stream sreal value to OB. */
kono
parents: 67
diff changeset
250
kono
parents: 67
diff changeset
251 void
kono
parents: 67
diff changeset
252 sreal::stream_out (struct output_block *ob)
kono
parents: 67
diff changeset
253 {
kono
parents: 67
diff changeset
254 streamer_write_hwi (ob, m_sig);
kono
parents: 67
diff changeset
255 streamer_write_hwi (ob, m_exp);
kono
parents: 67
diff changeset
256 }
kono
parents: 67
diff changeset
257
kono
parents: 67
diff changeset
258 /* Read sreal value from IB. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259
111
kono
parents: 67
diff changeset
260 sreal
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
261 sreal::stream_in (class lto_input_block *ib)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 {
111
kono
parents: 67
diff changeset
263 sreal val;
kono
parents: 67
diff changeset
264 val.m_sig = streamer_read_hwi (ib);
kono
parents: 67
diff changeset
265 val.m_exp = streamer_read_hwi (ib);
kono
parents: 67
diff changeset
266 return val;
kono
parents: 67
diff changeset
267 }
kono
parents: 67
diff changeset
268
kono
parents: 67
diff changeset
269 #if CHECKING_P
kono
parents: 67
diff changeset
270
kono
parents: 67
diff changeset
271 namespace selftest {
kono
parents: 67
diff changeset
272
kono
parents: 67
diff changeset
273 /* Selftests for sreals. */
kono
parents: 67
diff changeset
274
kono
parents: 67
diff changeset
275 /* Verify basic sreal operations. */
kono
parents: 67
diff changeset
276
kono
parents: 67
diff changeset
277 static void
kono
parents: 67
diff changeset
278 sreal_verify_basics (void)
kono
parents: 67
diff changeset
279 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 sreal minimum = INT_MIN/2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 sreal maximum = INT_MAX/2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282
111
kono
parents: 67
diff changeset
283 sreal seven = 7;
kono
parents: 67
diff changeset
284 sreal minus_two = -2;
kono
parents: 67
diff changeset
285 sreal minus_nine = -9;
kono
parents: 67
diff changeset
286
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 ASSERT_EQ (INT_MIN/2, minimum.to_int ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 ASSERT_EQ (INT_MAX/2, maximum.to_int ());
111
kono
parents: 67
diff changeset
289
kono
parents: 67
diff changeset
290 ASSERT_FALSE (minus_two < minus_two);
kono
parents: 67
diff changeset
291 ASSERT_FALSE (seven < seven);
kono
parents: 67
diff changeset
292 ASSERT_TRUE (seven > minus_two);
kono
parents: 67
diff changeset
293 ASSERT_TRUE (minus_two < seven);
kono
parents: 67
diff changeset
294 ASSERT_TRUE (minus_two != seven);
kono
parents: 67
diff changeset
295 ASSERT_EQ (minus_two, -2);
kono
parents: 67
diff changeset
296 ASSERT_EQ (seven, 7);
kono
parents: 67
diff changeset
297 ASSERT_EQ ((seven << 10) >> 10, 7);
kono
parents: 67
diff changeset
298 ASSERT_EQ (seven + minus_nine, -2);
kono
parents: 67
diff changeset
299 }
kono
parents: 67
diff changeset
300
kono
parents: 67
diff changeset
301 /* Helper function that performs basic arithmetics and comparison
kono
parents: 67
diff changeset
302 of given arguments A and B. */
kono
parents: 67
diff changeset
303
kono
parents: 67
diff changeset
304 static void
kono
parents: 67
diff changeset
305 verify_aritmetics (int64_t a, int64_t b)
kono
parents: 67
diff changeset
306 {
kono
parents: 67
diff changeset
307 ASSERT_EQ (a, -(-(sreal (a))).to_int ());
kono
parents: 67
diff changeset
308 ASSERT_EQ (a < b, sreal (a) < sreal (b));
kono
parents: 67
diff changeset
309 ASSERT_EQ (a <= b, sreal (a) <= sreal (b));
kono
parents: 67
diff changeset
310 ASSERT_EQ (a == b, sreal (a) == sreal (b));
kono
parents: 67
diff changeset
311 ASSERT_EQ (a != b, sreal (a) != sreal (b));
kono
parents: 67
diff changeset
312 ASSERT_EQ (a > b, sreal (a) > sreal (b));
kono
parents: 67
diff changeset
313 ASSERT_EQ (a >= b, sreal (a) >= sreal (b));
kono
parents: 67
diff changeset
314 ASSERT_EQ (a + b, (sreal (a) + sreal (b)).to_int ());
kono
parents: 67
diff changeset
315 ASSERT_EQ (a - b, (sreal (a) - sreal (b)).to_int ());
kono
parents: 67
diff changeset
316 ASSERT_EQ (b + a, (sreal (b) + sreal (a)).to_int ());
kono
parents: 67
diff changeset
317 ASSERT_EQ (b - a, (sreal (b) - sreal (a)).to_int ());
kono
parents: 67
diff changeset
318 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319
111
kono
parents: 67
diff changeset
320 /* Verify arithmetics for interesting numbers. */
kono
parents: 67
diff changeset
321
kono
parents: 67
diff changeset
322 static void
kono
parents: 67
diff changeset
323 sreal_verify_arithmetics (void)
kono
parents: 67
diff changeset
324 {
kono
parents: 67
diff changeset
325 int values[] = {-14123413, -7777, -17, -10, -2, 0, 17, 139, 1234123};
kono
parents: 67
diff changeset
326 unsigned c = sizeof (values) / sizeof (int);
kono
parents: 67
diff changeset
327
kono
parents: 67
diff changeset
328 for (unsigned i = 0; i < c; i++)
kono
parents: 67
diff changeset
329 for (unsigned j = 0; j < c; j++)
kono
parents: 67
diff changeset
330 {
kono
parents: 67
diff changeset
331 int a = values[i];
kono
parents: 67
diff changeset
332 int b = values[j];
kono
parents: 67
diff changeset
333
kono
parents: 67
diff changeset
334 verify_aritmetics (a, b);
kono
parents: 67
diff changeset
335 }
kono
parents: 67
diff changeset
336 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337
111
kono
parents: 67
diff changeset
338 /* Helper function that performs various shifting test of a given
kono
parents: 67
diff changeset
339 argument A. */
kono
parents: 67
diff changeset
340
kono
parents: 67
diff changeset
341 static void
kono
parents: 67
diff changeset
342 verify_shifting (int64_t a)
kono
parents: 67
diff changeset
343 {
kono
parents: 67
diff changeset
344 sreal v = a;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345
111
kono
parents: 67
diff changeset
346 for (unsigned i = 0; i < 16; i++)
kono
parents: 67
diff changeset
347 ASSERT_EQ (a << i, (v << i).to_int());
kono
parents: 67
diff changeset
348
kono
parents: 67
diff changeset
349 a = a << 16;
kono
parents: 67
diff changeset
350 v = v << 16;
kono
parents: 67
diff changeset
351
kono
parents: 67
diff changeset
352 for (unsigned i = 0; i < 16; i++)
kono
parents: 67
diff changeset
353 ASSERT_EQ (a >> i, (v >> i).to_int());
kono
parents: 67
diff changeset
354 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355
111
kono
parents: 67
diff changeset
356 /* Verify shifting for interesting numbers. */
kono
parents: 67
diff changeset
357
kono
parents: 67
diff changeset
358 static void
kono
parents: 67
diff changeset
359 sreal_verify_shifting (void)
kono
parents: 67
diff changeset
360 {
kono
parents: 67
diff changeset
361 int values[] = {0, 17, 32, 139, 1024, 55555, 1234123};
kono
parents: 67
diff changeset
362 unsigned c = sizeof (values) / sizeof (int);
kono
parents: 67
diff changeset
363
kono
parents: 67
diff changeset
364 for (unsigned i = 0; i < c; i++)
kono
parents: 67
diff changeset
365 verify_shifting (values[i]);
kono
parents: 67
diff changeset
366 }
kono
parents: 67
diff changeset
367
kono
parents: 67
diff changeset
368 /* Verify division by (of) a negative value. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369
111
kono
parents: 67
diff changeset
370 static void
kono
parents: 67
diff changeset
371 sreal_verify_negative_division (void)
kono
parents: 67
diff changeset
372 {
kono
parents: 67
diff changeset
373 ASSERT_EQ (sreal (1) / sreal (1), sreal (1));
kono
parents: 67
diff changeset
374 ASSERT_EQ (sreal (-1) / sreal (-1), sreal (1));
kono
parents: 67
diff changeset
375 ASSERT_EQ (sreal (-1234567) / sreal (-1234567), sreal (1));
kono
parents: 67
diff changeset
376 ASSERT_EQ (sreal (-1234567) / sreal (1234567), sreal (-1));
kono
parents: 67
diff changeset
377 ASSERT_EQ (sreal (1234567) / sreal (-1234567), sreal (-1));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 }
111
kono
parents: 67
diff changeset
379
kono
parents: 67
diff changeset
380 /* Run all of the selftests within this file. */
kono
parents: 67
diff changeset
381
kono
parents: 67
diff changeset
382 void sreal_c_tests ()
kono
parents: 67
diff changeset
383 {
kono
parents: 67
diff changeset
384 sreal_verify_basics ();
kono
parents: 67
diff changeset
385 sreal_verify_arithmetics ();
kono
parents: 67
diff changeset
386 sreal_verify_shifting ();
kono
parents: 67
diff changeset
387 sreal_verify_negative_division ();
kono
parents: 67
diff changeset
388 }
kono
parents: 67
diff changeset
389
kono
parents: 67
diff changeset
390 } // namespace selftest
kono
parents: 67
diff changeset
391 #endif /* CHECKING_P */