annotate libgcc/libgcc2.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:
diff changeset
1 /* More subroutines needed by GCC output code on some machines. */
kono
parents:
diff changeset
2 /* Compile this one with gcc. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3 /* Copyright (C) 1989-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
10 version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
15 for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 #include "tconfig.h"
kono
parents:
diff changeset
27 #include "tsystem.h"
kono
parents:
diff changeset
28 #include "coretypes.h"
kono
parents:
diff changeset
29 #include "tm.h"
kono
parents:
diff changeset
30 #include "libgcc_tm.h"
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 #ifdef HAVE_GAS_HIDDEN
kono
parents:
diff changeset
33 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
kono
parents:
diff changeset
34 #else
kono
parents:
diff changeset
35 #define ATTRIBUTE_HIDDEN
kono
parents:
diff changeset
36 #endif
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 /* Work out the largest "word" size that we can deal with on this target. */
kono
parents:
diff changeset
39 #if MIN_UNITS_PER_WORD > 4
kono
parents:
diff changeset
40 # define LIBGCC2_MAX_UNITS_PER_WORD 8
kono
parents:
diff changeset
41 #elif (MIN_UNITS_PER_WORD > 2 \
kono
parents:
diff changeset
42 || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4))
kono
parents:
diff changeset
43 # define LIBGCC2_MAX_UNITS_PER_WORD 4
kono
parents:
diff changeset
44 #else
kono
parents:
diff changeset
45 # define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD
kono
parents:
diff changeset
46 #endif
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 /* Work out what word size we are using for this compilation.
kono
parents:
diff changeset
49 The value can be set on the command line. */
kono
parents:
diff changeset
50 #ifndef LIBGCC2_UNITS_PER_WORD
kono
parents:
diff changeset
51 #define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD
kono
parents:
diff changeset
52 #endif
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 #if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 #include "libgcc2.h"
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 #ifdef DECLARE_LIBRARY_RENAMES
kono
parents:
diff changeset
59 DECLARE_LIBRARY_RENAMES
kono
parents:
diff changeset
60 #endif
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 #if defined (L_negdi2)
kono
parents:
diff changeset
63 DWtype
kono
parents:
diff changeset
64 __negdi2 (DWtype u)
kono
parents:
diff changeset
65 {
kono
parents:
diff changeset
66 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
67 const DWunion w = { {.low = -uu.s.low,
kono
parents:
diff changeset
68 .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 return w.ll;
kono
parents:
diff changeset
71 }
kono
parents:
diff changeset
72 #endif
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 #ifdef L_addvsi3
kono
parents:
diff changeset
75 Wtype
kono
parents:
diff changeset
76 __addvSI3 (Wtype a, Wtype b)
kono
parents:
diff changeset
77 {
kono
parents:
diff changeset
78 const Wtype w = (UWtype) a + (UWtype) b;
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 if (b >= 0 ? w < a : w > a)
kono
parents:
diff changeset
81 abort ();
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 return w;
kono
parents:
diff changeset
84 }
kono
parents:
diff changeset
85 #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
kono
parents:
diff changeset
86 SItype
kono
parents:
diff changeset
87 __addvsi3 (SItype a, SItype b)
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 const SItype w = (USItype) a + (USItype) b;
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 if (b >= 0 ? w < a : w > a)
kono
parents:
diff changeset
92 abort ();
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 return w;
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96 #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
kono
parents:
diff changeset
97 #endif
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 #ifdef L_addvdi3
kono
parents:
diff changeset
100 DWtype
kono
parents:
diff changeset
101 __addvDI3 (DWtype a, DWtype b)
kono
parents:
diff changeset
102 {
kono
parents:
diff changeset
103 const DWtype w = (UDWtype) a + (UDWtype) b;
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 if (b >= 0 ? w < a : w > a)
kono
parents:
diff changeset
106 abort ();
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 return w;
kono
parents:
diff changeset
109 }
kono
parents:
diff changeset
110 #endif
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 #ifdef L_subvsi3
kono
parents:
diff changeset
113 Wtype
kono
parents:
diff changeset
114 __subvSI3 (Wtype a, Wtype b)
kono
parents:
diff changeset
115 {
kono
parents:
diff changeset
116 const Wtype w = (UWtype) a - (UWtype) b;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 if (b >= 0 ? w > a : w < a)
kono
parents:
diff changeset
119 abort ();
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 return w;
kono
parents:
diff changeset
122 }
kono
parents:
diff changeset
123 #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
kono
parents:
diff changeset
124 SItype
kono
parents:
diff changeset
125 __subvsi3 (SItype a, SItype b)
kono
parents:
diff changeset
126 {
kono
parents:
diff changeset
127 const SItype w = (USItype) a - (USItype) b;
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 if (b >= 0 ? w > a : w < a)
kono
parents:
diff changeset
130 abort ();
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 return w;
kono
parents:
diff changeset
133 }
kono
parents:
diff changeset
134 #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
kono
parents:
diff changeset
135 #endif
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 #ifdef L_subvdi3
kono
parents:
diff changeset
138 DWtype
kono
parents:
diff changeset
139 __subvDI3 (DWtype a, DWtype b)
kono
parents:
diff changeset
140 {
kono
parents:
diff changeset
141 const DWtype w = (UDWtype) a - (UDWtype) b;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 if (b >= 0 ? w > a : w < a)
kono
parents:
diff changeset
144 abort ();
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 return w;
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148 #endif
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 #ifdef L_mulvsi3
kono
parents:
diff changeset
151 Wtype
kono
parents:
diff changeset
152 __mulvSI3 (Wtype a, Wtype b)
kono
parents:
diff changeset
153 {
kono
parents:
diff changeset
154 const DWtype w = (DWtype) a * (DWtype) b;
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
kono
parents:
diff changeset
157 abort ();
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 return w;
kono
parents:
diff changeset
160 }
kono
parents:
diff changeset
161 #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
kono
parents:
diff changeset
162 #undef WORD_SIZE
kono
parents:
diff changeset
163 #define WORD_SIZE (sizeof (SItype) * __CHAR_BIT__)
kono
parents:
diff changeset
164 SItype
kono
parents:
diff changeset
165 __mulvsi3 (SItype a, SItype b)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 const DItype w = (DItype) a * (DItype) b;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
kono
parents:
diff changeset
170 abort ();
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 return w;
kono
parents:
diff changeset
173 }
kono
parents:
diff changeset
174 #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
kono
parents:
diff changeset
175 #endif
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 #ifdef L_negvsi2
kono
parents:
diff changeset
178 Wtype
kono
parents:
diff changeset
179 __negvSI2 (Wtype a)
kono
parents:
diff changeset
180 {
kono
parents:
diff changeset
181 const Wtype w = -(UWtype) a;
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 if (a >= 0 ? w > 0 : w < 0)
kono
parents:
diff changeset
184 abort ();
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 return w;
kono
parents:
diff changeset
187 }
kono
parents:
diff changeset
188 #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
kono
parents:
diff changeset
189 SItype
kono
parents:
diff changeset
190 __negvsi2 (SItype a)
kono
parents:
diff changeset
191 {
kono
parents:
diff changeset
192 const SItype w = -(USItype) a;
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 if (a >= 0 ? w > 0 : w < 0)
kono
parents:
diff changeset
195 abort ();
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 return w;
kono
parents:
diff changeset
198 }
kono
parents:
diff changeset
199 #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
kono
parents:
diff changeset
200 #endif
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 #ifdef L_negvdi2
kono
parents:
diff changeset
203 DWtype
kono
parents:
diff changeset
204 __negvDI2 (DWtype a)
kono
parents:
diff changeset
205 {
kono
parents:
diff changeset
206 const DWtype w = -(UDWtype) a;
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 if (a >= 0 ? w > 0 : w < 0)
kono
parents:
diff changeset
209 abort ();
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 return w;
kono
parents:
diff changeset
212 }
kono
parents:
diff changeset
213 #endif
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 #ifdef L_absvsi2
kono
parents:
diff changeset
216 Wtype
kono
parents:
diff changeset
217 __absvSI2 (Wtype a)
kono
parents:
diff changeset
218 {
kono
parents:
diff changeset
219 Wtype w = a;
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 if (a < 0)
kono
parents:
diff changeset
222 #ifdef L_negvsi2
kono
parents:
diff changeset
223 w = __negvSI2 (a);
kono
parents:
diff changeset
224 #else
kono
parents:
diff changeset
225 w = -(UWtype) a;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 if (w < 0)
kono
parents:
diff changeset
228 abort ();
kono
parents:
diff changeset
229 #endif
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 return w;
kono
parents:
diff changeset
232 }
kono
parents:
diff changeset
233 #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
kono
parents:
diff changeset
234 SItype
kono
parents:
diff changeset
235 __absvsi2 (SItype a)
kono
parents:
diff changeset
236 {
kono
parents:
diff changeset
237 SItype w = a;
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 if (a < 0)
kono
parents:
diff changeset
240 #ifdef L_negvsi2
kono
parents:
diff changeset
241 w = __negvsi2 (a);
kono
parents:
diff changeset
242 #else
kono
parents:
diff changeset
243 w = -(USItype) a;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 if (w < 0)
kono
parents:
diff changeset
246 abort ();
kono
parents:
diff changeset
247 #endif
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 return w;
kono
parents:
diff changeset
250 }
kono
parents:
diff changeset
251 #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
kono
parents:
diff changeset
252 #endif
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 #ifdef L_absvdi2
kono
parents:
diff changeset
255 DWtype
kono
parents:
diff changeset
256 __absvDI2 (DWtype a)
kono
parents:
diff changeset
257 {
kono
parents:
diff changeset
258 DWtype w = a;
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 if (a < 0)
kono
parents:
diff changeset
261 #ifdef L_negvdi2
kono
parents:
diff changeset
262 w = __negvDI2 (a);
kono
parents:
diff changeset
263 #else
kono
parents:
diff changeset
264 w = -(UDWtype) a;
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 if (w < 0)
kono
parents:
diff changeset
267 abort ();
kono
parents:
diff changeset
268 #endif
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 return w;
kono
parents:
diff changeset
271 }
kono
parents:
diff changeset
272 #endif
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 #ifdef L_mulvdi3
kono
parents:
diff changeset
275 DWtype
kono
parents:
diff changeset
276 __mulvDI3 (DWtype u, DWtype v)
kono
parents:
diff changeset
277 {
kono
parents:
diff changeset
278 /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
kono
parents:
diff changeset
279 but the checked multiplication needs only two. */
kono
parents:
diff changeset
280 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
281 const DWunion vv = {.ll = v};
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1))
kono
parents:
diff changeset
284 {
kono
parents:
diff changeset
285 /* u fits in a single Wtype. */
kono
parents:
diff changeset
286 if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
kono
parents:
diff changeset
287 {
kono
parents:
diff changeset
288 /* v fits in a single Wtype as well. */
kono
parents:
diff changeset
289 /* A single multiplication. No overflow risk. */
kono
parents:
diff changeset
290 return (DWtype) uu.s.low * (DWtype) vv.s.low;
kono
parents:
diff changeset
291 }
kono
parents:
diff changeset
292 else
kono
parents:
diff changeset
293 {
kono
parents:
diff changeset
294 /* Two multiplications. */
kono
parents:
diff changeset
295 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
296 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
297 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
298 * (UDWtype) (UWtype) vv.s.high};
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 if (vv.s.high < 0)
kono
parents:
diff changeset
301 w1.s.high -= uu.s.low;
kono
parents:
diff changeset
302 if (uu.s.low < 0)
kono
parents:
diff changeset
303 w1.ll -= vv.ll;
kono
parents:
diff changeset
304 w1.ll += (UWtype) w0.s.high;
kono
parents:
diff changeset
305 if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
kono
parents:
diff changeset
306 {
kono
parents:
diff changeset
307 w0.s.high = w1.s.low;
kono
parents:
diff changeset
308 return w0.ll;
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310 }
kono
parents:
diff changeset
311 }
kono
parents:
diff changeset
312 else
kono
parents:
diff changeset
313 {
kono
parents:
diff changeset
314 if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 /* v fits into a single Wtype. */
kono
parents:
diff changeset
317 /* Two multiplications. */
kono
parents:
diff changeset
318 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
319 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
320 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
kono
parents:
diff changeset
321 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 if (uu.s.high < 0)
kono
parents:
diff changeset
324 w1.s.high -= vv.s.low;
kono
parents:
diff changeset
325 if (vv.s.low < 0)
kono
parents:
diff changeset
326 w1.ll -= uu.ll;
kono
parents:
diff changeset
327 w1.ll += (UWtype) w0.s.high;
kono
parents:
diff changeset
328 if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
kono
parents:
diff changeset
329 {
kono
parents:
diff changeset
330 w0.s.high = w1.s.low;
kono
parents:
diff changeset
331 return w0.ll;
kono
parents:
diff changeset
332 }
kono
parents:
diff changeset
333 }
kono
parents:
diff changeset
334 else
kono
parents:
diff changeset
335 {
kono
parents:
diff changeset
336 /* A few sign checks and a single multiplication. */
kono
parents:
diff changeset
337 if (uu.s.high >= 0)
kono
parents:
diff changeset
338 {
kono
parents:
diff changeset
339 if (vv.s.high >= 0)
kono
parents:
diff changeset
340 {
kono
parents:
diff changeset
341 if (uu.s.high == 0 && vv.s.high == 0)
kono
parents:
diff changeset
342 {
kono
parents:
diff changeset
343 const DWtype w = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
344 * (UDWtype) (UWtype) vv.s.low;
kono
parents:
diff changeset
345 if (__builtin_expect (w >= 0, 1))
kono
parents:
diff changeset
346 return w;
kono
parents:
diff changeset
347 }
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349 else
kono
parents:
diff changeset
350 {
kono
parents:
diff changeset
351 if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
kono
parents:
diff changeset
352 {
kono
parents:
diff changeset
353 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
354 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 ww.s.high -= uu.s.low;
kono
parents:
diff changeset
357 if (__builtin_expect (ww.s.high < 0, 1))
kono
parents:
diff changeset
358 return ww.ll;
kono
parents:
diff changeset
359 }
kono
parents:
diff changeset
360 }
kono
parents:
diff changeset
361 }
kono
parents:
diff changeset
362 else
kono
parents:
diff changeset
363 {
kono
parents:
diff changeset
364 if (vv.s.high >= 0)
kono
parents:
diff changeset
365 {
kono
parents:
diff changeset
366 if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
kono
parents:
diff changeset
367 {
kono
parents:
diff changeset
368 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
369 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 ww.s.high -= vv.s.low;
kono
parents:
diff changeset
372 if (__builtin_expect (ww.s.high < 0, 1))
kono
parents:
diff changeset
373 return ww.ll;
kono
parents:
diff changeset
374 }
kono
parents:
diff changeset
375 }
kono
parents:
diff changeset
376 else
kono
parents:
diff changeset
377 {
kono
parents:
diff changeset
378 if ((uu.s.high & vv.s.high) == (Wtype) -1
kono
parents:
diff changeset
379 && (uu.s.low | vv.s.low) != 0)
kono
parents:
diff changeset
380 {
kono
parents:
diff changeset
381 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
kono
parents:
diff changeset
382 * (UDWtype) (UWtype) vv.s.low};
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 ww.s.high -= uu.s.low;
kono
parents:
diff changeset
385 ww.s.high -= vv.s.low;
kono
parents:
diff changeset
386 if (__builtin_expect (ww.s.high >= 0, 1))
kono
parents:
diff changeset
387 return ww.ll;
kono
parents:
diff changeset
388 }
kono
parents:
diff changeset
389 }
kono
parents:
diff changeset
390 }
kono
parents:
diff changeset
391 }
kono
parents:
diff changeset
392 }
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 /* Overflow. */
kono
parents:
diff changeset
395 abort ();
kono
parents:
diff changeset
396 }
kono
parents:
diff changeset
397 #endif
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 /* Unless shift functions are defined with full ANSI prototypes,
kono
parents:
diff changeset
401 parameter b will be promoted to int if shift_count_type is smaller than an int. */
kono
parents:
diff changeset
402 #ifdef L_lshrdi3
kono
parents:
diff changeset
403 DWtype
kono
parents:
diff changeset
404 __lshrdi3 (DWtype u, shift_count_type b)
kono
parents:
diff changeset
405 {
kono
parents:
diff changeset
406 if (b == 0)
kono
parents:
diff changeset
407 return u;
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
410 const shift_count_type bm = W_TYPE_SIZE - b;
kono
parents:
diff changeset
411 DWunion w;
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 if (bm <= 0)
kono
parents:
diff changeset
414 {
kono
parents:
diff changeset
415 w.s.high = 0;
kono
parents:
diff changeset
416 w.s.low = (UWtype) uu.s.high >> -bm;
kono
parents:
diff changeset
417 }
kono
parents:
diff changeset
418 else
kono
parents:
diff changeset
419 {
kono
parents:
diff changeset
420 const UWtype carries = (UWtype) uu.s.high << bm;
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 w.s.high = (UWtype) uu.s.high >> b;
kono
parents:
diff changeset
423 w.s.low = ((UWtype) uu.s.low >> b) | carries;
kono
parents:
diff changeset
424 }
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 return w.ll;
kono
parents:
diff changeset
427 }
kono
parents:
diff changeset
428 #endif
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 #ifdef L_ashldi3
kono
parents:
diff changeset
431 DWtype
kono
parents:
diff changeset
432 __ashldi3 (DWtype u, shift_count_type b)
kono
parents:
diff changeset
433 {
kono
parents:
diff changeset
434 if (b == 0)
kono
parents:
diff changeset
435 return u;
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
438 const shift_count_type bm = W_TYPE_SIZE - b;
kono
parents:
diff changeset
439 DWunion w;
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 if (bm <= 0)
kono
parents:
diff changeset
442 {
kono
parents:
diff changeset
443 w.s.low = 0;
kono
parents:
diff changeset
444 w.s.high = (UWtype) uu.s.low << -bm;
kono
parents:
diff changeset
445 }
kono
parents:
diff changeset
446 else
kono
parents:
diff changeset
447 {
kono
parents:
diff changeset
448 const UWtype carries = (UWtype) uu.s.low >> bm;
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 w.s.low = (UWtype) uu.s.low << b;
kono
parents:
diff changeset
451 w.s.high = ((UWtype) uu.s.high << b) | carries;
kono
parents:
diff changeset
452 }
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 return w.ll;
kono
parents:
diff changeset
455 }
kono
parents:
diff changeset
456 #endif
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 #ifdef L_ashrdi3
kono
parents:
diff changeset
459 DWtype
kono
parents:
diff changeset
460 __ashrdi3 (DWtype u, shift_count_type b)
kono
parents:
diff changeset
461 {
kono
parents:
diff changeset
462 if (b == 0)
kono
parents:
diff changeset
463 return u;
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
466 const shift_count_type bm = W_TYPE_SIZE - b;
kono
parents:
diff changeset
467 DWunion w;
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 if (bm <= 0)
kono
parents:
diff changeset
470 {
kono
parents:
diff changeset
471 /* w.s.high = 1..1 or 0..0 */
kono
parents:
diff changeset
472 w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
kono
parents:
diff changeset
473 w.s.low = uu.s.high >> -bm;
kono
parents:
diff changeset
474 }
kono
parents:
diff changeset
475 else
kono
parents:
diff changeset
476 {
kono
parents:
diff changeset
477 const UWtype carries = (UWtype) uu.s.high << bm;
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 w.s.high = uu.s.high >> b;
kono
parents:
diff changeset
480 w.s.low = ((UWtype) uu.s.low >> b) | carries;
kono
parents:
diff changeset
481 }
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 return w.ll;
kono
parents:
diff changeset
484 }
kono
parents:
diff changeset
485 #endif
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 #ifdef L_bswapsi2
kono
parents:
diff changeset
488 SItype
kono
parents:
diff changeset
489 __bswapsi2 (SItype u)
kono
parents:
diff changeset
490 {
kono
parents:
diff changeset
491 return ((((u) & 0xff000000) >> 24)
kono
parents:
diff changeset
492 | (((u) & 0x00ff0000) >> 8)
kono
parents:
diff changeset
493 | (((u) & 0x0000ff00) << 8)
kono
parents:
diff changeset
494 | (((u) & 0x000000ff) << 24));
kono
parents:
diff changeset
495 }
kono
parents:
diff changeset
496 #endif
kono
parents:
diff changeset
497 #ifdef L_bswapdi2
kono
parents:
diff changeset
498 DItype
kono
parents:
diff changeset
499 __bswapdi2 (DItype u)
kono
parents:
diff changeset
500 {
kono
parents:
diff changeset
501 return ((((u) & 0xff00000000000000ull) >> 56)
kono
parents:
diff changeset
502 | (((u) & 0x00ff000000000000ull) >> 40)
kono
parents:
diff changeset
503 | (((u) & 0x0000ff0000000000ull) >> 24)
kono
parents:
diff changeset
504 | (((u) & 0x000000ff00000000ull) >> 8)
kono
parents:
diff changeset
505 | (((u) & 0x00000000ff000000ull) << 8)
kono
parents:
diff changeset
506 | (((u) & 0x0000000000ff0000ull) << 24)
kono
parents:
diff changeset
507 | (((u) & 0x000000000000ff00ull) << 40)
kono
parents:
diff changeset
508 | (((u) & 0x00000000000000ffull) << 56));
kono
parents:
diff changeset
509 }
kono
parents:
diff changeset
510 #endif
kono
parents:
diff changeset
511 #ifdef L_ffssi2
kono
parents:
diff changeset
512 #undef int
kono
parents:
diff changeset
513 int
kono
parents:
diff changeset
514 __ffsSI2 (UWtype u)
kono
parents:
diff changeset
515 {
kono
parents:
diff changeset
516 UWtype count;
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518 if (u == 0)
kono
parents:
diff changeset
519 return 0;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 count_trailing_zeros (count, u);
kono
parents:
diff changeset
522 return count + 1;
kono
parents:
diff changeset
523 }
kono
parents:
diff changeset
524 #endif
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 #ifdef L_ffsdi2
kono
parents:
diff changeset
527 #undef int
kono
parents:
diff changeset
528 int
kono
parents:
diff changeset
529 __ffsDI2 (DWtype u)
kono
parents:
diff changeset
530 {
kono
parents:
diff changeset
531 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
532 UWtype word, count, add;
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 if (uu.s.low != 0)
kono
parents:
diff changeset
535 word = uu.s.low, add = 0;
kono
parents:
diff changeset
536 else if (uu.s.high != 0)
kono
parents:
diff changeset
537 word = uu.s.high, add = W_TYPE_SIZE;
kono
parents:
diff changeset
538 else
kono
parents:
diff changeset
539 return 0;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 count_trailing_zeros (count, word);
kono
parents:
diff changeset
542 return count + add + 1;
kono
parents:
diff changeset
543 }
kono
parents:
diff changeset
544 #endif
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 #ifdef L_muldi3
kono
parents:
diff changeset
547 DWtype
kono
parents:
diff changeset
548 __muldi3 (DWtype u, DWtype v)
kono
parents:
diff changeset
549 {
kono
parents:
diff changeset
550 const DWunion uu = {.ll = u};
kono
parents:
diff changeset
551 const DWunion vv = {.ll = v};
kono
parents:
diff changeset
552 DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
kono
parents:
diff changeset
553
kono
parents:
diff changeset
554 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
kono
parents:
diff changeset
555 + (UWtype) uu.s.high * (UWtype) vv.s.low);
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 return w.ll;
kono
parents:
diff changeset
558 }
kono
parents:
diff changeset
559 #endif
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 #if (defined (L_udivdi3) || defined (L_divdi3) || \
kono
parents:
diff changeset
562 defined (L_umoddi3) || defined (L_moddi3))
kono
parents:
diff changeset
563 #if defined (sdiv_qrnnd)
kono
parents:
diff changeset
564 #define L_udiv_w_sdiv
kono
parents:
diff changeset
565 #endif
kono
parents:
diff changeset
566 #endif
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 #ifdef L_udiv_w_sdiv
kono
parents:
diff changeset
569 #if defined (sdiv_qrnnd)
kono
parents:
diff changeset
570 #if (defined (L_udivdi3) || defined (L_divdi3) || \
kono
parents:
diff changeset
571 defined (L_umoddi3) || defined (L_moddi3))
kono
parents:
diff changeset
572 static inline __attribute__ ((__always_inline__))
kono
parents:
diff changeset
573 #endif
kono
parents:
diff changeset
574 UWtype
kono
parents:
diff changeset
575 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
kono
parents:
diff changeset
576 {
kono
parents:
diff changeset
577 UWtype q, r;
kono
parents:
diff changeset
578 UWtype c0, c1, b1;
kono
parents:
diff changeset
579
kono
parents:
diff changeset
580 if ((Wtype) d >= 0)
kono
parents:
diff changeset
581 {
kono
parents:
diff changeset
582 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
kono
parents:
diff changeset
583 {
kono
parents:
diff changeset
584 /* Dividend, divisor, and quotient are nonnegative. */
kono
parents:
diff changeset
585 sdiv_qrnnd (q, r, a1, a0, d);
kono
parents:
diff changeset
586 }
kono
parents:
diff changeset
587 else
kono
parents:
diff changeset
588 {
kono
parents:
diff changeset
589 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */
kono
parents:
diff changeset
590 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
kono
parents:
diff changeset
591 /* Divide (c1*2^32 + c0) by d. */
kono
parents:
diff changeset
592 sdiv_qrnnd (q, r, c1, c0, d);
kono
parents:
diff changeset
593 /* Add 2^31 to quotient. */
kono
parents:
diff changeset
594 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
kono
parents:
diff changeset
595 }
kono
parents:
diff changeset
596 }
kono
parents:
diff changeset
597 else
kono
parents:
diff changeset
598 {
kono
parents:
diff changeset
599 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
kono
parents:
diff changeset
600 c1 = a1 >> 1; /* A/2 */
kono
parents:
diff changeset
601 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
kono
parents:
diff changeset
604 {
kono
parents:
diff changeset
605 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
kono
parents:
diff changeset
608 if ((d & 1) != 0)
kono
parents:
diff changeset
609 {
kono
parents:
diff changeset
610 if (r >= q)
kono
parents:
diff changeset
611 r = r - q;
kono
parents:
diff changeset
612 else if (q - r <= d)
kono
parents:
diff changeset
613 {
kono
parents:
diff changeset
614 r = r - q + d;
kono
parents:
diff changeset
615 q--;
kono
parents:
diff changeset
616 }
kono
parents:
diff changeset
617 else
kono
parents:
diff changeset
618 {
kono
parents:
diff changeset
619 r = r - q + 2*d;
kono
parents:
diff changeset
620 q -= 2;
kono
parents:
diff changeset
621 }
kono
parents:
diff changeset
622 }
kono
parents:
diff changeset
623 }
kono
parents:
diff changeset
624 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
kono
parents:
diff changeset
625 {
kono
parents:
diff changeset
626 c1 = (b1 - 1) - c1;
kono
parents:
diff changeset
627 c0 = ~c0; /* logical NOT */
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 q = ~q; /* (A/2)/b1 */
kono
parents:
diff changeset
632 r = (b1 - 1) - r;
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 r = 2*r + (a0 & 1); /* A/(2*b1) */
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 if ((d & 1) != 0)
kono
parents:
diff changeset
637 {
kono
parents:
diff changeset
638 if (r >= q)
kono
parents:
diff changeset
639 r = r - q;
kono
parents:
diff changeset
640 else if (q - r <= d)
kono
parents:
diff changeset
641 {
kono
parents:
diff changeset
642 r = r - q + d;
kono
parents:
diff changeset
643 q--;
kono
parents:
diff changeset
644 }
kono
parents:
diff changeset
645 else
kono
parents:
diff changeset
646 {
kono
parents:
diff changeset
647 r = r - q + 2*d;
kono
parents:
diff changeset
648 q -= 2;
kono
parents:
diff changeset
649 }
kono
parents:
diff changeset
650 }
kono
parents:
diff changeset
651 }
kono
parents:
diff changeset
652 else /* Implies c1 = b1 */
kono
parents:
diff changeset
653 { /* Hence a1 = d - 1 = 2*b1 - 1 */
kono
parents:
diff changeset
654 if (a0 >= -d)
kono
parents:
diff changeset
655 {
kono
parents:
diff changeset
656 q = -1;
kono
parents:
diff changeset
657 r = a0 + d;
kono
parents:
diff changeset
658 }
kono
parents:
diff changeset
659 else
kono
parents:
diff changeset
660 {
kono
parents:
diff changeset
661 q = -2;
kono
parents:
diff changeset
662 r = a0 + 2*d;
kono
parents:
diff changeset
663 }
kono
parents:
diff changeset
664 }
kono
parents:
diff changeset
665 }
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 *rp = r;
kono
parents:
diff changeset
668 return q;
kono
parents:
diff changeset
669 }
kono
parents:
diff changeset
670 #else
kono
parents:
diff changeset
671 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
kono
parents:
diff changeset
672 UWtype
kono
parents:
diff changeset
673 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
kono
parents:
diff changeset
674 UWtype a1 __attribute__ ((__unused__)),
kono
parents:
diff changeset
675 UWtype a0 __attribute__ ((__unused__)),
kono
parents:
diff changeset
676 UWtype d __attribute__ ((__unused__)))
kono
parents:
diff changeset
677 {
kono
parents:
diff changeset
678 return 0;
kono
parents:
diff changeset
679 }
kono
parents:
diff changeset
680 #endif
kono
parents:
diff changeset
681 #endif
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 #if (defined (L_udivdi3) || defined (L_divdi3) || \
kono
parents:
diff changeset
684 defined (L_umoddi3) || defined (L_moddi3) || \
kono
parents:
diff changeset
685 defined (L_divmoddi4))
kono
parents:
diff changeset
686 #define L_udivmoddi4
kono
parents:
diff changeset
687 #endif
kono
parents:
diff changeset
688
kono
parents:
diff changeset
689 #ifdef L_clz
kono
parents:
diff changeset
690 const UQItype __clz_tab[256] =
kono
parents:
diff changeset
691 {
kono
parents:
diff changeset
692 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
kono
parents:
diff changeset
693 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
kono
parents:
diff changeset
694 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
kono
parents:
diff changeset
695 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
kono
parents:
diff changeset
696 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
kono
parents:
diff changeset
697 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
kono
parents:
diff changeset
698 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
kono
parents:
diff changeset
699 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
kono
parents:
diff changeset
700 };
kono
parents:
diff changeset
701 #endif
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 #ifdef L_clzsi2
kono
parents:
diff changeset
704 #undef int
kono
parents:
diff changeset
705 int
kono
parents:
diff changeset
706 __clzSI2 (UWtype x)
kono
parents:
diff changeset
707 {
kono
parents:
diff changeset
708 Wtype ret;
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 count_leading_zeros (ret, x);
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 return ret;
kono
parents:
diff changeset
713 }
kono
parents:
diff changeset
714 #endif
kono
parents:
diff changeset
715
kono
parents:
diff changeset
716 #ifdef L_clzdi2
kono
parents:
diff changeset
717 #undef int
kono
parents:
diff changeset
718 int
kono
parents:
diff changeset
719 __clzDI2 (UDWtype x)
kono
parents:
diff changeset
720 {
kono
parents:
diff changeset
721 const DWunion uu = {.ll = x};
kono
parents:
diff changeset
722 UWtype word;
kono
parents:
diff changeset
723 Wtype ret, add;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 if (uu.s.high)
kono
parents:
diff changeset
726 word = uu.s.high, add = 0;
kono
parents:
diff changeset
727 else
kono
parents:
diff changeset
728 word = uu.s.low, add = W_TYPE_SIZE;
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 count_leading_zeros (ret, word);
kono
parents:
diff changeset
731 return ret + add;
kono
parents:
diff changeset
732 }
kono
parents:
diff changeset
733 #endif
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 #ifdef L_ctzsi2
kono
parents:
diff changeset
736 #undef int
kono
parents:
diff changeset
737 int
kono
parents:
diff changeset
738 __ctzSI2 (UWtype x)
kono
parents:
diff changeset
739 {
kono
parents:
diff changeset
740 Wtype ret;
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 count_trailing_zeros (ret, x);
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 return ret;
kono
parents:
diff changeset
745 }
kono
parents:
diff changeset
746 #endif
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 #ifdef L_ctzdi2
kono
parents:
diff changeset
749 #undef int
kono
parents:
diff changeset
750 int
kono
parents:
diff changeset
751 __ctzDI2 (UDWtype x)
kono
parents:
diff changeset
752 {
kono
parents:
diff changeset
753 const DWunion uu = {.ll = x};
kono
parents:
diff changeset
754 UWtype word;
kono
parents:
diff changeset
755 Wtype ret, add;
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 if (uu.s.low)
kono
parents:
diff changeset
758 word = uu.s.low, add = 0;
kono
parents:
diff changeset
759 else
kono
parents:
diff changeset
760 word = uu.s.high, add = W_TYPE_SIZE;
kono
parents:
diff changeset
761
kono
parents:
diff changeset
762 count_trailing_zeros (ret, word);
kono
parents:
diff changeset
763 return ret + add;
kono
parents:
diff changeset
764 }
kono
parents:
diff changeset
765 #endif
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 #ifdef L_clrsbsi2
kono
parents:
diff changeset
768 #undef int
kono
parents:
diff changeset
769 int
kono
parents:
diff changeset
770 __clrsbSI2 (Wtype x)
kono
parents:
diff changeset
771 {
kono
parents:
diff changeset
772 Wtype ret;
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 if (x < 0)
kono
parents:
diff changeset
775 x = ~x;
kono
parents:
diff changeset
776 if (x == 0)
kono
parents:
diff changeset
777 return W_TYPE_SIZE - 1;
kono
parents:
diff changeset
778 count_leading_zeros (ret, x);
kono
parents:
diff changeset
779 return ret - 1;
kono
parents:
diff changeset
780 }
kono
parents:
diff changeset
781 #endif
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 #ifdef L_clrsbdi2
kono
parents:
diff changeset
784 #undef int
kono
parents:
diff changeset
785 int
kono
parents:
diff changeset
786 __clrsbDI2 (DWtype x)
kono
parents:
diff changeset
787 {
kono
parents:
diff changeset
788 const DWunion uu = {.ll = x};
kono
parents:
diff changeset
789 UWtype word;
kono
parents:
diff changeset
790 Wtype ret, add;
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 if (uu.s.high == 0)
kono
parents:
diff changeset
793 word = uu.s.low, add = W_TYPE_SIZE;
kono
parents:
diff changeset
794 else if (uu.s.high == -1)
kono
parents:
diff changeset
795 word = ~uu.s.low, add = W_TYPE_SIZE;
kono
parents:
diff changeset
796 else if (uu.s.high >= 0)
kono
parents:
diff changeset
797 word = uu.s.high, add = 0;
kono
parents:
diff changeset
798 else
kono
parents:
diff changeset
799 word = ~uu.s.high, add = 0;
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 if (word == 0)
kono
parents:
diff changeset
802 ret = W_TYPE_SIZE;
kono
parents:
diff changeset
803 else
kono
parents:
diff changeset
804 count_leading_zeros (ret, word);
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 return ret + add - 1;
kono
parents:
diff changeset
807 }
kono
parents:
diff changeset
808 #endif
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 #ifdef L_popcount_tab
kono
parents:
diff changeset
811 const UQItype __popcount_tab[256] =
kono
parents:
diff changeset
812 {
kono
parents:
diff changeset
813 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
kono
parents:
diff changeset
814 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
kono
parents:
diff changeset
815 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
kono
parents:
diff changeset
816 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
kono
parents:
diff changeset
817 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
kono
parents:
diff changeset
818 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
kono
parents:
diff changeset
819 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
kono
parents:
diff changeset
820 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
kono
parents:
diff changeset
821 };
kono
parents:
diff changeset
822 #endif
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 #if defined(L_popcountsi2) || defined(L_popcountdi2)
kono
parents:
diff changeset
825 #define POPCOUNTCST2(x) (((UWtype) x << __CHAR_BIT__) | x)
kono
parents:
diff changeset
826 #define POPCOUNTCST4(x) (((UWtype) x << (2 * __CHAR_BIT__)) | x)
kono
parents:
diff changeset
827 #define POPCOUNTCST8(x) (((UWtype) x << (4 * __CHAR_BIT__)) | x)
kono
parents:
diff changeset
828 #if W_TYPE_SIZE == __CHAR_BIT__
kono
parents:
diff changeset
829 #define POPCOUNTCST(x) x
kono
parents:
diff changeset
830 #elif W_TYPE_SIZE == 2 * __CHAR_BIT__
kono
parents:
diff changeset
831 #define POPCOUNTCST(x) POPCOUNTCST2 (x)
kono
parents:
diff changeset
832 #elif W_TYPE_SIZE == 4 * __CHAR_BIT__
kono
parents:
diff changeset
833 #define POPCOUNTCST(x) POPCOUNTCST4 (POPCOUNTCST2 (x))
kono
parents:
diff changeset
834 #elif W_TYPE_SIZE == 8 * __CHAR_BIT__
kono
parents:
diff changeset
835 #define POPCOUNTCST(x) POPCOUNTCST8 (POPCOUNTCST4 (POPCOUNTCST2 (x)))
kono
parents:
diff changeset
836 #endif
kono
parents:
diff changeset
837 #endif
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 #ifdef L_popcountsi2
kono
parents:
diff changeset
840 #undef int
kono
parents:
diff changeset
841 int
kono
parents:
diff changeset
842 __popcountSI2 (UWtype x)
kono
parents:
diff changeset
843 {
kono
parents:
diff changeset
844 /* Force table lookup on targets like AVR and RL78 which only
kono
parents:
diff changeset
845 pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
kono
parents:
diff changeset
846 have 1, and other small word targets. */
kono
parents:
diff changeset
847 #if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && __CHAR_BIT__ == 8
kono
parents:
diff changeset
848 x = x - ((x >> 1) & POPCOUNTCST (0x55));
kono
parents:
diff changeset
849 x = (x & POPCOUNTCST (0x33)) + ((x >> 2) & POPCOUNTCST (0x33));
kono
parents:
diff changeset
850 x = (x + (x >> 4)) & POPCOUNTCST (0x0F);
kono
parents:
diff changeset
851 return (x * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - __CHAR_BIT__);
kono
parents:
diff changeset
852 #else
kono
parents:
diff changeset
853 int i, ret = 0;
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 for (i = 0; i < W_TYPE_SIZE; i += 8)
kono
parents:
diff changeset
856 ret += __popcount_tab[(x >> i) & 0xff];
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 return ret;
kono
parents:
diff changeset
859 #endif
kono
parents:
diff changeset
860 }
kono
parents:
diff changeset
861 #endif
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 #ifdef L_popcountdi2
kono
parents:
diff changeset
864 #undef int
kono
parents:
diff changeset
865 int
kono
parents:
diff changeset
866 __popcountDI2 (UDWtype x)
kono
parents:
diff changeset
867 {
kono
parents:
diff changeset
868 /* Force table lookup on targets like AVR and RL78 which only
kono
parents:
diff changeset
869 pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
kono
parents:
diff changeset
870 have 1, and other small word targets. */
kono
parents:
diff changeset
871 #if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && __CHAR_BIT__ == 8
kono
parents:
diff changeset
872 const DWunion uu = {.ll = x};
kono
parents:
diff changeset
873 UWtype x1 = uu.s.low, x2 = uu.s.high;
kono
parents:
diff changeset
874 x1 = x1 - ((x1 >> 1) & POPCOUNTCST (0x55));
kono
parents:
diff changeset
875 x2 = x2 - ((x2 >> 1) & POPCOUNTCST (0x55));
kono
parents:
diff changeset
876 x1 = (x1 & POPCOUNTCST (0x33)) + ((x1 >> 2) & POPCOUNTCST (0x33));
kono
parents:
diff changeset
877 x2 = (x2 & POPCOUNTCST (0x33)) + ((x2 >> 2) & POPCOUNTCST (0x33));
kono
parents:
diff changeset
878 x1 = (x1 + (x1 >> 4)) & POPCOUNTCST (0x0F);
kono
parents:
diff changeset
879 x2 = (x2 + (x2 >> 4)) & POPCOUNTCST (0x0F);
kono
parents:
diff changeset
880 x1 += x2;
kono
parents:
diff changeset
881 return (x1 * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - __CHAR_BIT__);
kono
parents:
diff changeset
882 #else
kono
parents:
diff changeset
883 int i, ret = 0;
kono
parents:
diff changeset
884
kono
parents:
diff changeset
885 for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
kono
parents:
diff changeset
886 ret += __popcount_tab[(x >> i) & 0xff];
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 return ret;
kono
parents:
diff changeset
889 #endif
kono
parents:
diff changeset
890 }
kono
parents:
diff changeset
891 #endif
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 #ifdef L_paritysi2
kono
parents:
diff changeset
894 #undef int
kono
parents:
diff changeset
895 int
kono
parents:
diff changeset
896 __paritySI2 (UWtype x)
kono
parents:
diff changeset
897 {
kono
parents:
diff changeset
898 #if W_TYPE_SIZE > 64
kono
parents:
diff changeset
899 # error "fill out the table"
kono
parents:
diff changeset
900 #endif
kono
parents:
diff changeset
901 #if W_TYPE_SIZE > 32
kono
parents:
diff changeset
902 x ^= x >> 32;
kono
parents:
diff changeset
903 #endif
kono
parents:
diff changeset
904 #if W_TYPE_SIZE > 16
kono
parents:
diff changeset
905 x ^= x >> 16;
kono
parents:
diff changeset
906 #endif
kono
parents:
diff changeset
907 x ^= x >> 8;
kono
parents:
diff changeset
908 x ^= x >> 4;
kono
parents:
diff changeset
909 x &= 0xf;
kono
parents:
diff changeset
910 return (0x6996 >> x) & 1;
kono
parents:
diff changeset
911 }
kono
parents:
diff changeset
912 #endif
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 #ifdef L_paritydi2
kono
parents:
diff changeset
915 #undef int
kono
parents:
diff changeset
916 int
kono
parents:
diff changeset
917 __parityDI2 (UDWtype x)
kono
parents:
diff changeset
918 {
kono
parents:
diff changeset
919 const DWunion uu = {.ll = x};
kono
parents:
diff changeset
920 UWtype nx = uu.s.low ^ uu.s.high;
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 #if W_TYPE_SIZE > 64
kono
parents:
diff changeset
923 # error "fill out the table"
kono
parents:
diff changeset
924 #endif
kono
parents:
diff changeset
925 #if W_TYPE_SIZE > 32
kono
parents:
diff changeset
926 nx ^= nx >> 32;
kono
parents:
diff changeset
927 #endif
kono
parents:
diff changeset
928 #if W_TYPE_SIZE > 16
kono
parents:
diff changeset
929 nx ^= nx >> 16;
kono
parents:
diff changeset
930 #endif
kono
parents:
diff changeset
931 nx ^= nx >> 8;
kono
parents:
diff changeset
932 nx ^= nx >> 4;
kono
parents:
diff changeset
933 nx &= 0xf;
kono
parents:
diff changeset
934 return (0x6996 >> nx) & 1;
kono
parents:
diff changeset
935 }
kono
parents:
diff changeset
936 #endif
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 #ifdef L_udivmoddi4
kono
parents:
diff changeset
939 #ifdef TARGET_HAS_NO_HW_DIVIDE
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 #if (defined (L_udivdi3) || defined (L_divdi3) || \
kono
parents:
diff changeset
942 defined (L_umoddi3) || defined (L_moddi3) || \
kono
parents:
diff changeset
943 defined (L_divmoddi4))
kono
parents:
diff changeset
944 static inline __attribute__ ((__always_inline__))
kono
parents:
diff changeset
945 #endif
kono
parents:
diff changeset
946 UDWtype
kono
parents:
diff changeset
947 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
kono
parents:
diff changeset
948 {
kono
parents:
diff changeset
949 UDWtype q = 0, r = n, y = d;
kono
parents:
diff changeset
950 UWtype lz1, lz2, i, k;
kono
parents:
diff changeset
951
kono
parents:
diff changeset
952 /* Implements align divisor shift dividend method. This algorithm
kono
parents:
diff changeset
953 aligns the divisor under the dividend and then perform number of
kono
parents:
diff changeset
954 test-subtract iterations which shift the dividend left. Number of
kono
parents:
diff changeset
955 iterations is k + 1 where k is the number of bit positions the
kono
parents:
diff changeset
956 divisor must be shifted left to align it under the dividend.
kono
parents:
diff changeset
957 quotient bits can be saved in the rightmost positions of the dividend
kono
parents:
diff changeset
958 as it shifts left on each test-subtract iteration. */
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 if (y <= r)
kono
parents:
diff changeset
961 {
kono
parents:
diff changeset
962 lz1 = __builtin_clzll (d);
kono
parents:
diff changeset
963 lz2 = __builtin_clzll (n);
kono
parents:
diff changeset
964
kono
parents:
diff changeset
965 k = lz1 - lz2;
kono
parents:
diff changeset
966 y = (y << k);
kono
parents:
diff changeset
967
kono
parents:
diff changeset
968 /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
kono
parents:
diff changeset
969 aligned divisor. Normal iteration can drops the high order bit
kono
parents:
diff changeset
970 of the dividend. Therefore, first test-subtract iteration is a
kono
parents:
diff changeset
971 special case, saving its quotient bit in a separate location and
kono
parents:
diff changeset
972 not shifting the dividend. */
kono
parents:
diff changeset
973 if (r >= y)
kono
parents:
diff changeset
974 {
kono
parents:
diff changeset
975 r = r - y;
kono
parents:
diff changeset
976 q = (1ULL << k);
kono
parents:
diff changeset
977 }
kono
parents:
diff changeset
978
kono
parents:
diff changeset
979 if (k > 0)
kono
parents:
diff changeset
980 {
kono
parents:
diff changeset
981 y = y >> 1;
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 /* k additional iterations where k regular test subtract shift
kono
parents:
diff changeset
984 dividend iterations are done. */
kono
parents:
diff changeset
985 i = k;
kono
parents:
diff changeset
986 do
kono
parents:
diff changeset
987 {
kono
parents:
diff changeset
988 if (r >= y)
kono
parents:
diff changeset
989 r = ((r - y) << 1) + 1;
kono
parents:
diff changeset
990 else
kono
parents:
diff changeset
991 r = (r << 1);
kono
parents:
diff changeset
992 i = i - 1;
kono
parents:
diff changeset
993 } while (i != 0);
kono
parents:
diff changeset
994
kono
parents:
diff changeset
995 /* First quotient bit is combined with the quotient bits resulting
kono
parents:
diff changeset
996 from the k regular iterations. */
kono
parents:
diff changeset
997 q = q + r;
kono
parents:
diff changeset
998 r = r >> k;
kono
parents:
diff changeset
999 q = q - (r << k);
kono
parents:
diff changeset
1000 }
kono
parents:
diff changeset
1001 }
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 if (rp)
kono
parents:
diff changeset
1004 *rp = r;
kono
parents:
diff changeset
1005 return q;
kono
parents:
diff changeset
1006 }
kono
parents:
diff changeset
1007 #else
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 #if (defined (L_udivdi3) || defined (L_divdi3) || \
kono
parents:
diff changeset
1010 defined (L_umoddi3) || defined (L_moddi3) || \
kono
parents:
diff changeset
1011 defined (L_divmoddi4))
kono
parents:
diff changeset
1012 static inline __attribute__ ((__always_inline__))
kono
parents:
diff changeset
1013 #endif
kono
parents:
diff changeset
1014 UDWtype
kono
parents:
diff changeset
1015 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
kono
parents:
diff changeset
1016 {
kono
parents:
diff changeset
1017 const DWunion nn = {.ll = n};
kono
parents:
diff changeset
1018 const DWunion dd = {.ll = d};
kono
parents:
diff changeset
1019 DWunion rr;
kono
parents:
diff changeset
1020 UWtype d0, d1, n0, n1, n2;
kono
parents:
diff changeset
1021 UWtype q0, q1;
kono
parents:
diff changeset
1022 UWtype b, bm;
kono
parents:
diff changeset
1023
kono
parents:
diff changeset
1024 d0 = dd.s.low;
kono
parents:
diff changeset
1025 d1 = dd.s.high;
kono
parents:
diff changeset
1026 n0 = nn.s.low;
kono
parents:
diff changeset
1027 n1 = nn.s.high;
kono
parents:
diff changeset
1028
kono
parents:
diff changeset
1029 #if !UDIV_NEEDS_NORMALIZATION
kono
parents:
diff changeset
1030 if (d1 == 0)
kono
parents:
diff changeset
1031 {
kono
parents:
diff changeset
1032 if (d0 > n1)
kono
parents:
diff changeset
1033 {
kono
parents:
diff changeset
1034 /* 0q = nn / 0D */
kono
parents:
diff changeset
1035
kono
parents:
diff changeset
1036 udiv_qrnnd (q0, n0, n1, n0, d0);
kono
parents:
diff changeset
1037 q1 = 0;
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 /* Remainder in n0. */
kono
parents:
diff changeset
1040 }
kono
parents:
diff changeset
1041 else
kono
parents:
diff changeset
1042 {
kono
parents:
diff changeset
1043 /* qq = NN / 0d */
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 if (d0 == 0)
kono
parents:
diff changeset
1046 d0 = 1 / d0; /* Divide intentionally by zero. */
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 udiv_qrnnd (q1, n1, 0, n1, d0);
kono
parents:
diff changeset
1049 udiv_qrnnd (q0, n0, n1, n0, d0);
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 /* Remainder in n0. */
kono
parents:
diff changeset
1052 }
kono
parents:
diff changeset
1053
kono
parents:
diff changeset
1054 if (rp != 0)
kono
parents:
diff changeset
1055 {
kono
parents:
diff changeset
1056 rr.s.low = n0;
kono
parents:
diff changeset
1057 rr.s.high = 0;
kono
parents:
diff changeset
1058 *rp = rr.ll;
kono
parents:
diff changeset
1059 }
kono
parents:
diff changeset
1060 }
kono
parents:
diff changeset
1061
kono
parents:
diff changeset
1062 #else /* UDIV_NEEDS_NORMALIZATION */
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 if (d1 == 0)
kono
parents:
diff changeset
1065 {
kono
parents:
diff changeset
1066 if (d0 > n1)
kono
parents:
diff changeset
1067 {
kono
parents:
diff changeset
1068 /* 0q = nn / 0D */
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 count_leading_zeros (bm, d0);
kono
parents:
diff changeset
1071
kono
parents:
diff changeset
1072 if (bm != 0)
kono
parents:
diff changeset
1073 {
kono
parents:
diff changeset
1074 /* Normalize, i.e. make the most significant bit of the
kono
parents:
diff changeset
1075 denominator set. */
kono
parents:
diff changeset
1076
kono
parents:
diff changeset
1077 d0 = d0 << bm;
kono
parents:
diff changeset
1078 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
kono
parents:
diff changeset
1079 n0 = n0 << bm;
kono
parents:
diff changeset
1080 }
kono
parents:
diff changeset
1081
kono
parents:
diff changeset
1082 udiv_qrnnd (q0, n0, n1, n0, d0);
kono
parents:
diff changeset
1083 q1 = 0;
kono
parents:
diff changeset
1084
kono
parents:
diff changeset
1085 /* Remainder in n0 >> bm. */
kono
parents:
diff changeset
1086 }
kono
parents:
diff changeset
1087 else
kono
parents:
diff changeset
1088 {
kono
parents:
diff changeset
1089 /* qq = NN / 0d */
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 if (d0 == 0)
kono
parents:
diff changeset
1092 d0 = 1 / d0; /* Divide intentionally by zero. */
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 count_leading_zeros (bm, d0);
kono
parents:
diff changeset
1095
kono
parents:
diff changeset
1096 if (bm == 0)
kono
parents:
diff changeset
1097 {
kono
parents:
diff changeset
1098 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
kono
parents:
diff changeset
1099 conclude (the most significant bit of n1 is set) /\ (the
kono
parents:
diff changeset
1100 leading quotient digit q1 = 1).
kono
parents:
diff changeset
1101
kono
parents:
diff changeset
1102 This special case is necessary, not an optimization.
kono
parents:
diff changeset
1103 (Shifts counts of W_TYPE_SIZE are undefined.) */
kono
parents:
diff changeset
1104
kono
parents:
diff changeset
1105 n1 -= d0;
kono
parents:
diff changeset
1106 q1 = 1;
kono
parents:
diff changeset
1107 }
kono
parents:
diff changeset
1108 else
kono
parents:
diff changeset
1109 {
kono
parents:
diff changeset
1110 /* Normalize. */
kono
parents:
diff changeset
1111
kono
parents:
diff changeset
1112 b = W_TYPE_SIZE - bm;
kono
parents:
diff changeset
1113
kono
parents:
diff changeset
1114 d0 = d0 << bm;
kono
parents:
diff changeset
1115 n2 = n1 >> b;
kono
parents:
diff changeset
1116 n1 = (n1 << bm) | (n0 >> b);
kono
parents:
diff changeset
1117 n0 = n0 << bm;
kono
parents:
diff changeset
1118
kono
parents:
diff changeset
1119 udiv_qrnnd (q1, n1, n2, n1, d0);
kono
parents:
diff changeset
1120 }
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 /* n1 != d0... */
kono
parents:
diff changeset
1123
kono
parents:
diff changeset
1124 udiv_qrnnd (q0, n0, n1, n0, d0);
kono
parents:
diff changeset
1125
kono
parents:
diff changeset
1126 /* Remainder in n0 >> bm. */
kono
parents:
diff changeset
1127 }
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 if (rp != 0)
kono
parents:
diff changeset
1130 {
kono
parents:
diff changeset
1131 rr.s.low = n0 >> bm;
kono
parents:
diff changeset
1132 rr.s.high = 0;
kono
parents:
diff changeset
1133 *rp = rr.ll;
kono
parents:
diff changeset
1134 }
kono
parents:
diff changeset
1135 }
kono
parents:
diff changeset
1136 #endif /* UDIV_NEEDS_NORMALIZATION */
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 else
kono
parents:
diff changeset
1139 {
kono
parents:
diff changeset
1140 if (d1 > n1)
kono
parents:
diff changeset
1141 {
kono
parents:
diff changeset
1142 /* 00 = nn / DD */
kono
parents:
diff changeset
1143
kono
parents:
diff changeset
1144 q0 = 0;
kono
parents:
diff changeset
1145 q1 = 0;
kono
parents:
diff changeset
1146
kono
parents:
diff changeset
1147 /* Remainder in n1n0. */
kono
parents:
diff changeset
1148 if (rp != 0)
kono
parents:
diff changeset
1149 {
kono
parents:
diff changeset
1150 rr.s.low = n0;
kono
parents:
diff changeset
1151 rr.s.high = n1;
kono
parents:
diff changeset
1152 *rp = rr.ll;
kono
parents:
diff changeset
1153 }
kono
parents:
diff changeset
1154 }
kono
parents:
diff changeset
1155 else
kono
parents:
diff changeset
1156 {
kono
parents:
diff changeset
1157 /* 0q = NN / dd */
kono
parents:
diff changeset
1158
kono
parents:
diff changeset
1159 count_leading_zeros (bm, d1);
kono
parents:
diff changeset
1160 if (bm == 0)
kono
parents:
diff changeset
1161 {
kono
parents:
diff changeset
1162 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
kono
parents:
diff changeset
1163 conclude (the most significant bit of n1 is set) /\ (the
kono
parents:
diff changeset
1164 quotient digit q0 = 0 or 1).
kono
parents:
diff changeset
1165
kono
parents:
diff changeset
1166 This special case is necessary, not an optimization. */
kono
parents:
diff changeset
1167
kono
parents:
diff changeset
1168 /* The condition on the next line takes advantage of that
kono
parents:
diff changeset
1169 n1 >= d1 (true due to program flow). */
kono
parents:
diff changeset
1170 if (n1 > d1 || n0 >= d0)
kono
parents:
diff changeset
1171 {
kono
parents:
diff changeset
1172 q0 = 1;
kono
parents:
diff changeset
1173 sub_ddmmss (n1, n0, n1, n0, d1, d0);
kono
parents:
diff changeset
1174 }
kono
parents:
diff changeset
1175 else
kono
parents:
diff changeset
1176 q0 = 0;
kono
parents:
diff changeset
1177
kono
parents:
diff changeset
1178 q1 = 0;
kono
parents:
diff changeset
1179
kono
parents:
diff changeset
1180 if (rp != 0)
kono
parents:
diff changeset
1181 {
kono
parents:
diff changeset
1182 rr.s.low = n0;
kono
parents:
diff changeset
1183 rr.s.high = n1;
kono
parents:
diff changeset
1184 *rp = rr.ll;
kono
parents:
diff changeset
1185 }
kono
parents:
diff changeset
1186 }
kono
parents:
diff changeset
1187 else
kono
parents:
diff changeset
1188 {
kono
parents:
diff changeset
1189 UWtype m1, m0;
kono
parents:
diff changeset
1190 /* Normalize. */
kono
parents:
diff changeset
1191
kono
parents:
diff changeset
1192 b = W_TYPE_SIZE - bm;
kono
parents:
diff changeset
1193
kono
parents:
diff changeset
1194 d1 = (d1 << bm) | (d0 >> b);
kono
parents:
diff changeset
1195 d0 = d0 << bm;
kono
parents:
diff changeset
1196 n2 = n1 >> b;
kono
parents:
diff changeset
1197 n1 = (n1 << bm) | (n0 >> b);
kono
parents:
diff changeset
1198 n0 = n0 << bm;
kono
parents:
diff changeset
1199
kono
parents:
diff changeset
1200 udiv_qrnnd (q0, n1, n2, n1, d1);
kono
parents:
diff changeset
1201 umul_ppmm (m1, m0, q0, d0);
kono
parents:
diff changeset
1202
kono
parents:
diff changeset
1203 if (m1 > n1 || (m1 == n1 && m0 > n0))
kono
parents:
diff changeset
1204 {
kono
parents:
diff changeset
1205 q0--;
kono
parents:
diff changeset
1206 sub_ddmmss (m1, m0, m1, m0, d1, d0);
kono
parents:
diff changeset
1207 }
kono
parents:
diff changeset
1208
kono
parents:
diff changeset
1209 q1 = 0;
kono
parents:
diff changeset
1210
kono
parents:
diff changeset
1211 /* Remainder in (n1n0 - m1m0) >> bm. */
kono
parents:
diff changeset
1212 if (rp != 0)
kono
parents:
diff changeset
1213 {
kono
parents:
diff changeset
1214 sub_ddmmss (n1, n0, n1, n0, m1, m0);
kono
parents:
diff changeset
1215 rr.s.low = (n1 << b) | (n0 >> bm);
kono
parents:
diff changeset
1216 rr.s.high = n1 >> bm;
kono
parents:
diff changeset
1217 *rp = rr.ll;
kono
parents:
diff changeset
1218 }
kono
parents:
diff changeset
1219 }
kono
parents:
diff changeset
1220 }
kono
parents:
diff changeset
1221 }
kono
parents:
diff changeset
1222
kono
parents:
diff changeset
1223 const DWunion ww = {{.low = q0, .high = q1}};
kono
parents:
diff changeset
1224 return ww.ll;
kono
parents:
diff changeset
1225 }
kono
parents:
diff changeset
1226 #endif
kono
parents:
diff changeset
1227 #endif
kono
parents:
diff changeset
1228
kono
parents:
diff changeset
1229 #ifdef L_divdi3
kono
parents:
diff changeset
1230 DWtype
kono
parents:
diff changeset
1231 __divdi3 (DWtype u, DWtype v)
kono
parents:
diff changeset
1232 {
kono
parents:
diff changeset
1233 Wtype c = 0;
kono
parents:
diff changeset
1234 DWunion uu = {.ll = u};
kono
parents:
diff changeset
1235 DWunion vv = {.ll = v};
kono
parents:
diff changeset
1236 DWtype w;
kono
parents:
diff changeset
1237
kono
parents:
diff changeset
1238 if (uu.s.high < 0)
kono
parents:
diff changeset
1239 c = ~c,
kono
parents:
diff changeset
1240 uu.ll = -uu.ll;
kono
parents:
diff changeset
1241 if (vv.s.high < 0)
kono
parents:
diff changeset
1242 c = ~c,
kono
parents:
diff changeset
1243 vv.ll = -vv.ll;
kono
parents:
diff changeset
1244
kono
parents:
diff changeset
1245 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
kono
parents:
diff changeset
1246 if (c)
kono
parents:
diff changeset
1247 w = -w;
kono
parents:
diff changeset
1248
kono
parents:
diff changeset
1249 return w;
kono
parents:
diff changeset
1250 }
kono
parents:
diff changeset
1251 #endif
kono
parents:
diff changeset
1252
kono
parents:
diff changeset
1253 #ifdef L_moddi3
kono
parents:
diff changeset
1254 DWtype
kono
parents:
diff changeset
1255 __moddi3 (DWtype u, DWtype v)
kono
parents:
diff changeset
1256 {
kono
parents:
diff changeset
1257 Wtype c = 0;
kono
parents:
diff changeset
1258 DWunion uu = {.ll = u};
kono
parents:
diff changeset
1259 DWunion vv = {.ll = v};
kono
parents:
diff changeset
1260 DWtype w;
kono
parents:
diff changeset
1261
kono
parents:
diff changeset
1262 if (uu.s.high < 0)
kono
parents:
diff changeset
1263 c = ~c,
kono
parents:
diff changeset
1264 uu.ll = -uu.ll;
kono
parents:
diff changeset
1265 if (vv.s.high < 0)
kono
parents:
diff changeset
1266 vv.ll = -vv.ll;
kono
parents:
diff changeset
1267
kono
parents:
diff changeset
1268 (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
kono
parents:
diff changeset
1269 if (c)
kono
parents:
diff changeset
1270 w = -w;
kono
parents:
diff changeset
1271
kono
parents:
diff changeset
1272 return w;
kono
parents:
diff changeset
1273 }
kono
parents:
diff changeset
1274 #endif
kono
parents:
diff changeset
1275
kono
parents:
diff changeset
1276 #ifdef L_divmoddi4
kono
parents:
diff changeset
1277 DWtype
kono
parents:
diff changeset
1278 __divmoddi4 (DWtype u, DWtype v, DWtype *rp)
kono
parents:
diff changeset
1279 {
kono
parents:
diff changeset
1280 Wtype c1 = 0, c2 = 0;
kono
parents:
diff changeset
1281 DWunion uu = {.ll = u};
kono
parents:
diff changeset
1282 DWunion vv = {.ll = v};
kono
parents:
diff changeset
1283 DWtype w;
kono
parents:
diff changeset
1284 DWtype r;
kono
parents:
diff changeset
1285
kono
parents:
diff changeset
1286 if (uu.s.high < 0)
kono
parents:
diff changeset
1287 c1 = ~c1, c2 = ~c2,
kono
parents:
diff changeset
1288 uu.ll = -uu.ll;
kono
parents:
diff changeset
1289 if (vv.s.high < 0)
kono
parents:
diff changeset
1290 c1 = ~c1,
kono
parents:
diff changeset
1291 vv.ll = -vv.ll;
kono
parents:
diff changeset
1292
kono
parents:
diff changeset
1293 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&r);
kono
parents:
diff changeset
1294 if (c1)
kono
parents:
diff changeset
1295 w = -w;
kono
parents:
diff changeset
1296 if (c2)
kono
parents:
diff changeset
1297 r = -r;
kono
parents:
diff changeset
1298
kono
parents:
diff changeset
1299 *rp = r;
kono
parents:
diff changeset
1300 return w;
kono
parents:
diff changeset
1301 }
kono
parents:
diff changeset
1302 #endif
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 #ifdef L_umoddi3
kono
parents:
diff changeset
1305 UDWtype
kono
parents:
diff changeset
1306 __umoddi3 (UDWtype u, UDWtype v)
kono
parents:
diff changeset
1307 {
kono
parents:
diff changeset
1308 UDWtype w;
kono
parents:
diff changeset
1309
kono
parents:
diff changeset
1310 (void) __udivmoddi4 (u, v, &w);
kono
parents:
diff changeset
1311
kono
parents:
diff changeset
1312 return w;
kono
parents:
diff changeset
1313 }
kono
parents:
diff changeset
1314 #endif
kono
parents:
diff changeset
1315
kono
parents:
diff changeset
1316 #ifdef L_udivdi3
kono
parents:
diff changeset
1317 UDWtype
kono
parents:
diff changeset
1318 __udivdi3 (UDWtype n, UDWtype d)
kono
parents:
diff changeset
1319 {
kono
parents:
diff changeset
1320 return __udivmoddi4 (n, d, (UDWtype *) 0);
kono
parents:
diff changeset
1321 }
kono
parents:
diff changeset
1322 #endif
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 #ifdef L_cmpdi2
kono
parents:
diff changeset
1325 cmp_return_type
kono
parents:
diff changeset
1326 __cmpdi2 (DWtype a, DWtype b)
kono
parents:
diff changeset
1327 {
kono
parents:
diff changeset
1328 const DWunion au = {.ll = a};
kono
parents:
diff changeset
1329 const DWunion bu = {.ll = b};
kono
parents:
diff changeset
1330
kono
parents:
diff changeset
1331 if (au.s.high < bu.s.high)
kono
parents:
diff changeset
1332 return 0;
kono
parents:
diff changeset
1333 else if (au.s.high > bu.s.high)
kono
parents:
diff changeset
1334 return 2;
kono
parents:
diff changeset
1335 if ((UWtype) au.s.low < (UWtype) bu.s.low)
kono
parents:
diff changeset
1336 return 0;
kono
parents:
diff changeset
1337 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
kono
parents:
diff changeset
1338 return 2;
kono
parents:
diff changeset
1339 return 1;
kono
parents:
diff changeset
1340 }
kono
parents:
diff changeset
1341 #endif
kono
parents:
diff changeset
1342
kono
parents:
diff changeset
1343 #ifdef L_ucmpdi2
kono
parents:
diff changeset
1344 cmp_return_type
kono
parents:
diff changeset
1345 __ucmpdi2 (DWtype a, DWtype b)
kono
parents:
diff changeset
1346 {
kono
parents:
diff changeset
1347 const DWunion au = {.ll = a};
kono
parents:
diff changeset
1348 const DWunion bu = {.ll = b};
kono
parents:
diff changeset
1349
kono
parents:
diff changeset
1350 if ((UWtype) au.s.high < (UWtype) bu.s.high)
kono
parents:
diff changeset
1351 return 0;
kono
parents:
diff changeset
1352 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
kono
parents:
diff changeset
1353 return 2;
kono
parents:
diff changeset
1354 if ((UWtype) au.s.low < (UWtype) bu.s.low)
kono
parents:
diff changeset
1355 return 0;
kono
parents:
diff changeset
1356 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
kono
parents:
diff changeset
1357 return 2;
kono
parents:
diff changeset
1358 return 1;
kono
parents:
diff changeset
1359 }
kono
parents:
diff changeset
1360 #endif
kono
parents:
diff changeset
1361
kono
parents:
diff changeset
1362 #if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
kono
parents:
diff changeset
1363 UDWtype
kono
parents:
diff changeset
1364 __fixunstfDI (TFtype a)
kono
parents:
diff changeset
1365 {
kono
parents:
diff changeset
1366 if (a < 0)
kono
parents:
diff changeset
1367 return 0;
kono
parents:
diff changeset
1368
kono
parents:
diff changeset
1369 /* Compute high word of result, as a flonum. */
kono
parents:
diff changeset
1370 const TFtype b = (a / Wtype_MAXp1_F);
kono
parents:
diff changeset
1371 /* Convert that to fixed (but not to DWtype!),
kono
parents:
diff changeset
1372 and shift it into the high word. */
kono
parents:
diff changeset
1373 UDWtype v = (UWtype) b;
kono
parents:
diff changeset
1374 v <<= W_TYPE_SIZE;
kono
parents:
diff changeset
1375 /* Remove high part from the TFtype, leaving the low part as flonum. */
kono
parents:
diff changeset
1376 a -= (TFtype)v;
kono
parents:
diff changeset
1377 /* Convert that to fixed (but not to DWtype!) and add it in.
kono
parents:
diff changeset
1378 Sometimes A comes out negative. This is significant, since
kono
parents:
diff changeset
1379 A has more bits than a long int does. */
kono
parents:
diff changeset
1380 if (a < 0)
kono
parents:
diff changeset
1381 v -= (UWtype) (- a);
kono
parents:
diff changeset
1382 else
kono
parents:
diff changeset
1383 v += (UWtype) a;
kono
parents:
diff changeset
1384 return v;
kono
parents:
diff changeset
1385 }
kono
parents:
diff changeset
1386 #endif
kono
parents:
diff changeset
1387
kono
parents:
diff changeset
1388 #if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
kono
parents:
diff changeset
1389 DWtype
kono
parents:
diff changeset
1390 __fixtfdi (TFtype a)
kono
parents:
diff changeset
1391 {
kono
parents:
diff changeset
1392 if (a < 0)
kono
parents:
diff changeset
1393 return - __fixunstfDI (-a);
kono
parents:
diff changeset
1394 return __fixunstfDI (a);
kono
parents:
diff changeset
1395 }
kono
parents:
diff changeset
1396 #endif
kono
parents:
diff changeset
1397
kono
parents:
diff changeset
1398 #if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
kono
parents:
diff changeset
1399 UDWtype
kono
parents:
diff changeset
1400 __fixunsxfDI (XFtype a)
kono
parents:
diff changeset
1401 {
kono
parents:
diff changeset
1402 if (a < 0)
kono
parents:
diff changeset
1403 return 0;
kono
parents:
diff changeset
1404
kono
parents:
diff changeset
1405 /* Compute high word of result, as a flonum. */
kono
parents:
diff changeset
1406 const XFtype b = (a / Wtype_MAXp1_F);
kono
parents:
diff changeset
1407 /* Convert that to fixed (but not to DWtype!),
kono
parents:
diff changeset
1408 and shift it into the high word. */
kono
parents:
diff changeset
1409 UDWtype v = (UWtype) b;
kono
parents:
diff changeset
1410 v <<= W_TYPE_SIZE;
kono
parents:
diff changeset
1411 /* Remove high part from the XFtype, leaving the low part as flonum. */
kono
parents:
diff changeset
1412 a -= (XFtype)v;
kono
parents:
diff changeset
1413 /* Convert that to fixed (but not to DWtype!) and add it in.
kono
parents:
diff changeset
1414 Sometimes A comes out negative. This is significant, since
kono
parents:
diff changeset
1415 A has more bits than a long int does. */
kono
parents:
diff changeset
1416 if (a < 0)
kono
parents:
diff changeset
1417 v -= (UWtype) (- a);
kono
parents:
diff changeset
1418 else
kono
parents:
diff changeset
1419 v += (UWtype) a;
kono
parents:
diff changeset
1420 return v;
kono
parents:
diff changeset
1421 }
kono
parents:
diff changeset
1422 #endif
kono
parents:
diff changeset
1423
kono
parents:
diff changeset
1424 #if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
kono
parents:
diff changeset
1425 DWtype
kono
parents:
diff changeset
1426 __fixxfdi (XFtype a)
kono
parents:
diff changeset
1427 {
kono
parents:
diff changeset
1428 if (a < 0)
kono
parents:
diff changeset
1429 return - __fixunsxfDI (-a);
kono
parents:
diff changeset
1430 return __fixunsxfDI (a);
kono
parents:
diff changeset
1431 }
kono
parents:
diff changeset
1432 #endif
kono
parents:
diff changeset
1433
kono
parents:
diff changeset
1434 #if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
kono
parents:
diff changeset
1435 UDWtype
kono
parents:
diff changeset
1436 __fixunsdfDI (DFtype a)
kono
parents:
diff changeset
1437 {
kono
parents:
diff changeset
1438 /* Get high part of result. The division here will just moves the radix
kono
parents:
diff changeset
1439 point and will not cause any rounding. Then the conversion to integral
kono
parents:
diff changeset
1440 type chops result as desired. */
kono
parents:
diff changeset
1441 const UWtype hi = a / Wtype_MAXp1_F;
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 /* Get low part of result. Convert `hi' to floating type and scale it back,
kono
parents:
diff changeset
1444 then subtract this from the number being converted. This leaves the low
kono
parents:
diff changeset
1445 part. Convert that to integral type. */
kono
parents:
diff changeset
1446 const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 /* Assemble result from the two parts. */
kono
parents:
diff changeset
1449 return ((UDWtype) hi << W_TYPE_SIZE) | lo;
kono
parents:
diff changeset
1450 }
kono
parents:
diff changeset
1451 #endif
kono
parents:
diff changeset
1452
kono
parents:
diff changeset
1453 #if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
kono
parents:
diff changeset
1454 DWtype
kono
parents:
diff changeset
1455 __fixdfdi (DFtype a)
kono
parents:
diff changeset
1456 {
kono
parents:
diff changeset
1457 if (a < 0)
kono
parents:
diff changeset
1458 return - __fixunsdfDI (-a);
kono
parents:
diff changeset
1459 return __fixunsdfDI (a);
kono
parents:
diff changeset
1460 }
kono
parents:
diff changeset
1461 #endif
kono
parents:
diff changeset
1462
kono
parents:
diff changeset
1463 #if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE
kono
parents:
diff changeset
1464 UDWtype
kono
parents:
diff changeset
1465 __fixunssfDI (SFtype a)
kono
parents:
diff changeset
1466 {
kono
parents:
diff changeset
1467 #if LIBGCC2_HAS_DF_MODE
kono
parents:
diff changeset
1468 /* Convert the SFtype to a DFtype, because that is surely not going
kono
parents:
diff changeset
1469 to lose any bits. Some day someone else can write a faster version
kono
parents:
diff changeset
1470 that avoids converting to DFtype, and verify it really works right. */
kono
parents:
diff changeset
1471 const DFtype dfa = a;
kono
parents:
diff changeset
1472
kono
parents:
diff changeset
1473 /* Get high part of result. The division here will just moves the radix
kono
parents:
diff changeset
1474 point and will not cause any rounding. Then the conversion to integral
kono
parents:
diff changeset
1475 type chops result as desired. */
kono
parents:
diff changeset
1476 const UWtype hi = dfa / Wtype_MAXp1_F;
kono
parents:
diff changeset
1477
kono
parents:
diff changeset
1478 /* Get low part of result. Convert `hi' to floating type and scale it back,
kono
parents:
diff changeset
1479 then subtract this from the number being converted. This leaves the low
kono
parents:
diff changeset
1480 part. Convert that to integral type. */
kono
parents:
diff changeset
1481 const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
kono
parents:
diff changeset
1482
kono
parents:
diff changeset
1483 /* Assemble result from the two parts. */
kono
parents:
diff changeset
1484 return ((UDWtype) hi << W_TYPE_SIZE) | lo;
kono
parents:
diff changeset
1485 #elif FLT_MANT_DIG < W_TYPE_SIZE
kono
parents:
diff changeset
1486 if (a < 1)
kono
parents:
diff changeset
1487 return 0;
kono
parents:
diff changeset
1488 if (a < Wtype_MAXp1_F)
kono
parents:
diff changeset
1489 return (UWtype)a;
kono
parents:
diff changeset
1490 if (a < Wtype_MAXp1_F * Wtype_MAXp1_F)
kono
parents:
diff changeset
1491 {
kono
parents:
diff changeset
1492 /* Since we know that there are fewer significant bits in the SFmode
kono
parents:
diff changeset
1493 quantity than in a word, we know that we can convert out all the
kono
parents:
diff changeset
1494 significant bits in one step, and thus avoid losing bits. */
kono
parents:
diff changeset
1495
kono
parents:
diff changeset
1496 /* ??? This following loop essentially performs frexpf. If we could
kono
parents:
diff changeset
1497 use the real libm function, or poke at the actual bits of the fp
kono
parents:
diff changeset
1498 format, it would be significantly faster. */
kono
parents:
diff changeset
1499
kono
parents:
diff changeset
1500 UWtype shift = 0, counter;
kono
parents:
diff changeset
1501 SFtype msb;
kono
parents:
diff changeset
1502
kono
parents:
diff changeset
1503 a /= Wtype_MAXp1_F;
kono
parents:
diff changeset
1504 for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1)
kono
parents:
diff changeset
1505 {
kono
parents:
diff changeset
1506 SFtype counterf = (UWtype)1 << counter;
kono
parents:
diff changeset
1507 if (a >= counterf)
kono
parents:
diff changeset
1508 {
kono
parents:
diff changeset
1509 shift |= counter;
kono
parents:
diff changeset
1510 a /= counterf;
kono
parents:
diff changeset
1511 }
kono
parents:
diff changeset
1512 }
kono
parents:
diff changeset
1513
kono
parents:
diff changeset
1514 /* Rescale into the range of one word, extract the bits of that
kono
parents:
diff changeset
1515 one word, and shift the result into position. */
kono
parents:
diff changeset
1516 a *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1517 counter = a;
kono
parents:
diff changeset
1518 return (DWtype)counter << shift;
kono
parents:
diff changeset
1519 }
kono
parents:
diff changeset
1520 return -1;
kono
parents:
diff changeset
1521 #else
kono
parents:
diff changeset
1522 # error
kono
parents:
diff changeset
1523 #endif
kono
parents:
diff changeset
1524 }
kono
parents:
diff changeset
1525 #endif
kono
parents:
diff changeset
1526
kono
parents:
diff changeset
1527 #if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE
kono
parents:
diff changeset
1528 DWtype
kono
parents:
diff changeset
1529 __fixsfdi (SFtype a)
kono
parents:
diff changeset
1530 {
kono
parents:
diff changeset
1531 if (a < 0)
kono
parents:
diff changeset
1532 return - __fixunssfDI (-a);
kono
parents:
diff changeset
1533 return __fixunssfDI (a);
kono
parents:
diff changeset
1534 }
kono
parents:
diff changeset
1535 #endif
kono
parents:
diff changeset
1536
kono
parents:
diff changeset
1537 #if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
kono
parents:
diff changeset
1538 XFtype
kono
parents:
diff changeset
1539 __floatdixf (DWtype u)
kono
parents:
diff changeset
1540 {
kono
parents:
diff changeset
1541 #if W_TYPE_SIZE > __LIBGCC_XF_MANT_DIG__
kono
parents:
diff changeset
1542 # error
kono
parents:
diff changeset
1543 #endif
kono
parents:
diff changeset
1544 XFtype d = (Wtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1545 d *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1546 d += (UWtype)u;
kono
parents:
diff changeset
1547 return d;
kono
parents:
diff changeset
1548 }
kono
parents:
diff changeset
1549 #endif
kono
parents:
diff changeset
1550
kono
parents:
diff changeset
1551 #if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE
kono
parents:
diff changeset
1552 XFtype
kono
parents:
diff changeset
1553 __floatundixf (UDWtype u)
kono
parents:
diff changeset
1554 {
kono
parents:
diff changeset
1555 #if W_TYPE_SIZE > __LIBGCC_XF_MANT_DIG__
kono
parents:
diff changeset
1556 # error
kono
parents:
diff changeset
1557 #endif
kono
parents:
diff changeset
1558 XFtype d = (UWtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1559 d *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1560 d += (UWtype)u;
kono
parents:
diff changeset
1561 return d;
kono
parents:
diff changeset
1562 }
kono
parents:
diff changeset
1563 #endif
kono
parents:
diff changeset
1564
kono
parents:
diff changeset
1565 #if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
kono
parents:
diff changeset
1566 TFtype
kono
parents:
diff changeset
1567 __floatditf (DWtype u)
kono
parents:
diff changeset
1568 {
kono
parents:
diff changeset
1569 #if W_TYPE_SIZE > __LIBGCC_TF_MANT_DIG__
kono
parents:
diff changeset
1570 # error
kono
parents:
diff changeset
1571 #endif
kono
parents:
diff changeset
1572 TFtype d = (Wtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1573 d *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1574 d += (UWtype)u;
kono
parents:
diff changeset
1575 return d;
kono
parents:
diff changeset
1576 }
kono
parents:
diff changeset
1577 #endif
kono
parents:
diff changeset
1578
kono
parents:
diff changeset
1579 #if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE
kono
parents:
diff changeset
1580 TFtype
kono
parents:
diff changeset
1581 __floatunditf (UDWtype u)
kono
parents:
diff changeset
1582 {
kono
parents:
diff changeset
1583 #if W_TYPE_SIZE > __LIBGCC_TF_MANT_DIG__
kono
parents:
diff changeset
1584 # error
kono
parents:
diff changeset
1585 #endif
kono
parents:
diff changeset
1586 TFtype d = (UWtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1587 d *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1588 d += (UWtype)u;
kono
parents:
diff changeset
1589 return d;
kono
parents:
diff changeset
1590 }
kono
parents:
diff changeset
1591 #endif
kono
parents:
diff changeset
1592
kono
parents:
diff changeset
1593 #if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \
kono
parents:
diff changeset
1594 || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
kono
parents:
diff changeset
1595 #define DI_SIZE (W_TYPE_SIZE * 2)
kono
parents:
diff changeset
1596 #define F_MODE_OK(SIZE) \
kono
parents:
diff changeset
1597 (SIZE < DI_SIZE \
kono
parents:
diff changeset
1598 && SIZE > (DI_SIZE - SIZE + FSSIZE) \
kono
parents:
diff changeset
1599 && !AVOID_FP_TYPE_CONVERSION(SIZE))
kono
parents:
diff changeset
1600 #if defined(L_floatdisf)
kono
parents:
diff changeset
1601 #define FUNC __floatdisf
kono
parents:
diff changeset
1602 #define FSTYPE SFtype
kono
parents:
diff changeset
1603 #define FSSIZE __LIBGCC_SF_MANT_DIG__
kono
parents:
diff changeset
1604 #else
kono
parents:
diff changeset
1605 #define FUNC __floatdidf
kono
parents:
diff changeset
1606 #define FSTYPE DFtype
kono
parents:
diff changeset
1607 #define FSSIZE __LIBGCC_DF_MANT_DIG__
kono
parents:
diff changeset
1608 #endif
kono
parents:
diff changeset
1609
kono
parents:
diff changeset
1610 FSTYPE
kono
parents:
diff changeset
1611 FUNC (DWtype u)
kono
parents:
diff changeset
1612 {
kono
parents:
diff changeset
1613 #if FSSIZE >= W_TYPE_SIZE
kono
parents:
diff changeset
1614 /* When the word size is small, we never get any rounding error. */
kono
parents:
diff changeset
1615 FSTYPE f = (Wtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1616 f *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1617 f += (UWtype)u;
kono
parents:
diff changeset
1618 return f;
kono
parents:
diff changeset
1619 #elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__)) \
kono
parents:
diff changeset
1620 || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__)) \
kono
parents:
diff changeset
1621 || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
kono
parents:
diff changeset
1622
kono
parents:
diff changeset
1623 #if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__))
kono
parents:
diff changeset
1624 # define FSIZE __LIBGCC_DF_MANT_DIG__
kono
parents:
diff changeset
1625 # define FTYPE DFtype
kono
parents:
diff changeset
1626 #elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__))
kono
parents:
diff changeset
1627 # define FSIZE __LIBGCC_XF_MANT_DIG__
kono
parents:
diff changeset
1628 # define FTYPE XFtype
kono
parents:
diff changeset
1629 #elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
kono
parents:
diff changeset
1630 # define FSIZE __LIBGCC_TF_MANT_DIG__
kono
parents:
diff changeset
1631 # define FTYPE TFtype
kono
parents:
diff changeset
1632 #else
kono
parents:
diff changeset
1633 # error
kono
parents:
diff changeset
1634 #endif
kono
parents:
diff changeset
1635
kono
parents:
diff changeset
1636 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
kono
parents:
diff changeset
1637
kono
parents:
diff changeset
1638 /* Protect against double-rounding error.
kono
parents:
diff changeset
1639 Represent any low-order bits, that might be truncated by a bit that
kono
parents:
diff changeset
1640 won't be lost. The bit can go in anywhere below the rounding position
kono
parents:
diff changeset
1641 of the FSTYPE. A fixed mask and bit position handles all usual
kono
parents:
diff changeset
1642 configurations. */
kono
parents:
diff changeset
1643 if (! (- ((DWtype) 1 << FSIZE) < u
kono
parents:
diff changeset
1644 && u < ((DWtype) 1 << FSIZE)))
kono
parents:
diff changeset
1645 {
kono
parents:
diff changeset
1646 if ((UDWtype) u & (REP_BIT - 1))
kono
parents:
diff changeset
1647 {
kono
parents:
diff changeset
1648 u &= ~ (REP_BIT - 1);
kono
parents:
diff changeset
1649 u |= REP_BIT;
kono
parents:
diff changeset
1650 }
kono
parents:
diff changeset
1651 }
kono
parents:
diff changeset
1652
kono
parents:
diff changeset
1653 /* Do the calculation in a wider type so that we don't lose any of
kono
parents:
diff changeset
1654 the precision of the high word while multiplying it. */
kono
parents:
diff changeset
1655 FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1656 f *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1657 f += (UWtype)u;
kono
parents:
diff changeset
1658 return (FSTYPE) f;
kono
parents:
diff changeset
1659 #else
kono
parents:
diff changeset
1660 #if FSSIZE >= W_TYPE_SIZE - 2
kono
parents:
diff changeset
1661 # error
kono
parents:
diff changeset
1662 #endif
kono
parents:
diff changeset
1663 /* Finally, the word size is larger than the number of bits in the
kono
parents:
diff changeset
1664 required FSTYPE, and we've got no suitable wider type. The only
kono
parents:
diff changeset
1665 way to avoid double rounding is to special case the
kono
parents:
diff changeset
1666 extraction. */
kono
parents:
diff changeset
1667
kono
parents:
diff changeset
1668 /* If there are no high bits set, fall back to one conversion. */
kono
parents:
diff changeset
1669 if ((Wtype)u == u)
kono
parents:
diff changeset
1670 return (FSTYPE)(Wtype)u;
kono
parents:
diff changeset
1671
kono
parents:
diff changeset
1672 /* Otherwise, find the power of two. */
kono
parents:
diff changeset
1673 Wtype hi = u >> W_TYPE_SIZE;
kono
parents:
diff changeset
1674 if (hi < 0)
kono
parents:
diff changeset
1675 hi = -(UWtype) hi;
kono
parents:
diff changeset
1676
kono
parents:
diff changeset
1677 UWtype count, shift;
kono
parents:
diff changeset
1678 #if !defined (COUNT_LEADING_ZEROS_0) || COUNT_LEADING_ZEROS_0 != W_TYPE_SIZE
kono
parents:
diff changeset
1679 if (hi == 0)
kono
parents:
diff changeset
1680 count = W_TYPE_SIZE;
kono
parents:
diff changeset
1681 else
kono
parents:
diff changeset
1682 #endif
kono
parents:
diff changeset
1683 count_leading_zeros (count, hi);
kono
parents:
diff changeset
1684
kono
parents:
diff changeset
1685 /* No leading bits means u == minimum. */
kono
parents:
diff changeset
1686 if (count == 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1687 return Wtype_MAXp1_F * (FSTYPE) (hi | ((UWtype) u != 0));
111
kono
parents:
diff changeset
1688
kono
parents:
diff changeset
1689 shift = 1 + W_TYPE_SIZE - count;
kono
parents:
diff changeset
1690
kono
parents:
diff changeset
1691 /* Shift down the most significant bits. */
kono
parents:
diff changeset
1692 hi = u >> shift;
kono
parents:
diff changeset
1693
kono
parents:
diff changeset
1694 /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
kono
parents:
diff changeset
1695 if ((UWtype)u << (W_TYPE_SIZE - shift))
kono
parents:
diff changeset
1696 hi |= 1;
kono
parents:
diff changeset
1697
kono
parents:
diff changeset
1698 /* Convert the one word of data, and rescale. */
kono
parents:
diff changeset
1699 FSTYPE f = hi, e;
kono
parents:
diff changeset
1700 if (shift == W_TYPE_SIZE)
kono
parents:
diff changeset
1701 e = Wtype_MAXp1_F;
kono
parents:
diff changeset
1702 /* The following two cases could be merged if we knew that the target
kono
parents:
diff changeset
1703 supported a native unsigned->float conversion. More often, we only
kono
parents:
diff changeset
1704 have a signed conversion, and have to add extra fixup code. */
kono
parents:
diff changeset
1705 else if (shift == W_TYPE_SIZE - 1)
kono
parents:
diff changeset
1706 e = Wtype_MAXp1_F / 2;
kono
parents:
diff changeset
1707 else
kono
parents:
diff changeset
1708 e = (Wtype)1 << shift;
kono
parents:
diff changeset
1709 return f * e;
kono
parents:
diff changeset
1710 #endif
kono
parents:
diff changeset
1711 }
kono
parents:
diff changeset
1712 #endif
kono
parents:
diff changeset
1713
kono
parents:
diff changeset
1714 #if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \
kono
parents:
diff changeset
1715 || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
kono
parents:
diff changeset
1716 #define DI_SIZE (W_TYPE_SIZE * 2)
kono
parents:
diff changeset
1717 #define F_MODE_OK(SIZE) \
kono
parents:
diff changeset
1718 (SIZE < DI_SIZE \
kono
parents:
diff changeset
1719 && SIZE > (DI_SIZE - SIZE + FSSIZE) \
kono
parents:
diff changeset
1720 && !AVOID_FP_TYPE_CONVERSION(SIZE))
kono
parents:
diff changeset
1721 #if defined(L_floatundisf)
kono
parents:
diff changeset
1722 #define FUNC __floatundisf
kono
parents:
diff changeset
1723 #define FSTYPE SFtype
kono
parents:
diff changeset
1724 #define FSSIZE __LIBGCC_SF_MANT_DIG__
kono
parents:
diff changeset
1725 #else
kono
parents:
diff changeset
1726 #define FUNC __floatundidf
kono
parents:
diff changeset
1727 #define FSTYPE DFtype
kono
parents:
diff changeset
1728 #define FSSIZE __LIBGCC_DF_MANT_DIG__
kono
parents:
diff changeset
1729 #endif
kono
parents:
diff changeset
1730
kono
parents:
diff changeset
1731 FSTYPE
kono
parents:
diff changeset
1732 FUNC (UDWtype u)
kono
parents:
diff changeset
1733 {
kono
parents:
diff changeset
1734 #if FSSIZE >= W_TYPE_SIZE
kono
parents:
diff changeset
1735 /* When the word size is small, we never get any rounding error. */
kono
parents:
diff changeset
1736 FSTYPE f = (UWtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1737 f *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1738 f += (UWtype)u;
kono
parents:
diff changeset
1739 return f;
kono
parents:
diff changeset
1740 #elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__)) \
kono
parents:
diff changeset
1741 || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__)) \
kono
parents:
diff changeset
1742 || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
kono
parents:
diff changeset
1743
kono
parents:
diff changeset
1744 #if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__))
kono
parents:
diff changeset
1745 # define FSIZE __LIBGCC_DF_MANT_DIG__
kono
parents:
diff changeset
1746 # define FTYPE DFtype
kono
parents:
diff changeset
1747 #elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__))
kono
parents:
diff changeset
1748 # define FSIZE __LIBGCC_XF_MANT_DIG__
kono
parents:
diff changeset
1749 # define FTYPE XFtype
kono
parents:
diff changeset
1750 #elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
kono
parents:
diff changeset
1751 # define FSIZE __LIBGCC_TF_MANT_DIG__
kono
parents:
diff changeset
1752 # define FTYPE TFtype
kono
parents:
diff changeset
1753 #else
kono
parents:
diff changeset
1754 # error
kono
parents:
diff changeset
1755 #endif
kono
parents:
diff changeset
1756
kono
parents:
diff changeset
1757 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
kono
parents:
diff changeset
1758
kono
parents:
diff changeset
1759 /* Protect against double-rounding error.
kono
parents:
diff changeset
1760 Represent any low-order bits, that might be truncated by a bit that
kono
parents:
diff changeset
1761 won't be lost. The bit can go in anywhere below the rounding position
kono
parents:
diff changeset
1762 of the FSTYPE. A fixed mask and bit position handles all usual
kono
parents:
diff changeset
1763 configurations. */
kono
parents:
diff changeset
1764 if (u >= ((UDWtype) 1 << FSIZE))
kono
parents:
diff changeset
1765 {
kono
parents:
diff changeset
1766 if ((UDWtype) u & (REP_BIT - 1))
kono
parents:
diff changeset
1767 {
kono
parents:
diff changeset
1768 u &= ~ (REP_BIT - 1);
kono
parents:
diff changeset
1769 u |= REP_BIT;
kono
parents:
diff changeset
1770 }
kono
parents:
diff changeset
1771 }
kono
parents:
diff changeset
1772
kono
parents:
diff changeset
1773 /* Do the calculation in a wider type so that we don't lose any of
kono
parents:
diff changeset
1774 the precision of the high word while multiplying it. */
kono
parents:
diff changeset
1775 FTYPE f = (UWtype) (u >> W_TYPE_SIZE);
kono
parents:
diff changeset
1776 f *= Wtype_MAXp1_F;
kono
parents:
diff changeset
1777 f += (UWtype)u;
kono
parents:
diff changeset
1778 return (FSTYPE) f;
kono
parents:
diff changeset
1779 #else
kono
parents:
diff changeset
1780 #if FSSIZE == W_TYPE_SIZE - 1
kono
parents:
diff changeset
1781 # error
kono
parents:
diff changeset
1782 #endif
kono
parents:
diff changeset
1783 /* Finally, the word size is larger than the number of bits in the
kono
parents:
diff changeset
1784 required FSTYPE, and we've got no suitable wider type. The only
kono
parents:
diff changeset
1785 way to avoid double rounding is to special case the
kono
parents:
diff changeset
1786 extraction. */
kono
parents:
diff changeset
1787
kono
parents:
diff changeset
1788 /* If there are no high bits set, fall back to one conversion. */
kono
parents:
diff changeset
1789 if ((UWtype)u == u)
kono
parents:
diff changeset
1790 return (FSTYPE)(UWtype)u;
kono
parents:
diff changeset
1791
kono
parents:
diff changeset
1792 /* Otherwise, find the power of two. */
kono
parents:
diff changeset
1793 UWtype hi = u >> W_TYPE_SIZE;
kono
parents:
diff changeset
1794
kono
parents:
diff changeset
1795 UWtype count, shift;
kono
parents:
diff changeset
1796 count_leading_zeros (count, hi);
kono
parents:
diff changeset
1797
kono
parents:
diff changeset
1798 shift = W_TYPE_SIZE - count;
kono
parents:
diff changeset
1799
kono
parents:
diff changeset
1800 /* Shift down the most significant bits. */
kono
parents:
diff changeset
1801 hi = u >> shift;
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
kono
parents:
diff changeset
1804 if ((UWtype)u << (W_TYPE_SIZE - shift))
kono
parents:
diff changeset
1805 hi |= 1;
kono
parents:
diff changeset
1806
kono
parents:
diff changeset
1807 /* Convert the one word of data, and rescale. */
kono
parents:
diff changeset
1808 FSTYPE f = hi, e;
kono
parents:
diff changeset
1809 if (shift == W_TYPE_SIZE)
kono
parents:
diff changeset
1810 e = Wtype_MAXp1_F;
kono
parents:
diff changeset
1811 /* The following two cases could be merged if we knew that the target
kono
parents:
diff changeset
1812 supported a native unsigned->float conversion. More often, we only
kono
parents:
diff changeset
1813 have a signed conversion, and have to add extra fixup code. */
kono
parents:
diff changeset
1814 else if (shift == W_TYPE_SIZE - 1)
kono
parents:
diff changeset
1815 e = Wtype_MAXp1_F / 2;
kono
parents:
diff changeset
1816 else
kono
parents:
diff changeset
1817 e = (Wtype)1 << shift;
kono
parents:
diff changeset
1818 return f * e;
kono
parents:
diff changeset
1819 #endif
kono
parents:
diff changeset
1820 }
kono
parents:
diff changeset
1821 #endif
kono
parents:
diff changeset
1822
kono
parents:
diff changeset
1823 #if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
kono
parents:
diff changeset
1824 UWtype
kono
parents:
diff changeset
1825 __fixunsxfSI (XFtype a)
kono
parents:
diff changeset
1826 {
kono
parents:
diff changeset
1827 if (a >= - (DFtype) Wtype_MIN)
kono
parents:
diff changeset
1828 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
kono
parents:
diff changeset
1829 return (Wtype) a;
kono
parents:
diff changeset
1830 }
kono
parents:
diff changeset
1831 #endif
kono
parents:
diff changeset
1832
kono
parents:
diff changeset
1833 #if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
kono
parents:
diff changeset
1834 UWtype
kono
parents:
diff changeset
1835 __fixunsdfSI (DFtype a)
kono
parents:
diff changeset
1836 {
kono
parents:
diff changeset
1837 if (a >= - (DFtype) Wtype_MIN)
kono
parents:
diff changeset
1838 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
kono
parents:
diff changeset
1839 return (Wtype) a;
kono
parents:
diff changeset
1840 }
kono
parents:
diff changeset
1841 #endif
kono
parents:
diff changeset
1842
kono
parents:
diff changeset
1843 #if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE
kono
parents:
diff changeset
1844 UWtype
kono
parents:
diff changeset
1845 __fixunssfSI (SFtype a)
kono
parents:
diff changeset
1846 {
kono
parents:
diff changeset
1847 if (a >= - (SFtype) Wtype_MIN)
kono
parents:
diff changeset
1848 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
kono
parents:
diff changeset
1849 return (Wtype) a;
kono
parents:
diff changeset
1850 }
kono
parents:
diff changeset
1851 #endif
kono
parents:
diff changeset
1852
kono
parents:
diff changeset
1853 /* Integer power helper used from __builtin_powi for non-constant
kono
parents:
diff changeset
1854 exponents. */
kono
parents:
diff changeset
1855
kono
parents:
diff changeset
1856 #if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \
kono
parents:
diff changeset
1857 || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \
kono
parents:
diff changeset
1858 || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \
kono
parents:
diff changeset
1859 || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE)
kono
parents:
diff changeset
1860 # if defined(L_powisf2)
kono
parents:
diff changeset
1861 # define TYPE SFtype
kono
parents:
diff changeset
1862 # define NAME __powisf2
kono
parents:
diff changeset
1863 # elif defined(L_powidf2)
kono
parents:
diff changeset
1864 # define TYPE DFtype
kono
parents:
diff changeset
1865 # define NAME __powidf2
kono
parents:
diff changeset
1866 # elif defined(L_powixf2)
kono
parents:
diff changeset
1867 # define TYPE XFtype
kono
parents:
diff changeset
1868 # define NAME __powixf2
kono
parents:
diff changeset
1869 # elif defined(L_powitf2)
kono
parents:
diff changeset
1870 # define TYPE TFtype
kono
parents:
diff changeset
1871 # define NAME __powitf2
kono
parents:
diff changeset
1872 # endif
kono
parents:
diff changeset
1873
kono
parents:
diff changeset
1874 #undef int
kono
parents:
diff changeset
1875 #undef unsigned
kono
parents:
diff changeset
1876 TYPE
kono
parents:
diff changeset
1877 NAME (TYPE x, int m)
kono
parents:
diff changeset
1878 {
kono
parents:
diff changeset
1879 unsigned int n = m < 0 ? -m : m;
kono
parents:
diff changeset
1880 TYPE y = n % 2 ? x : 1;
kono
parents:
diff changeset
1881 while (n >>= 1)
kono
parents:
diff changeset
1882 {
kono
parents:
diff changeset
1883 x = x * x;
kono
parents:
diff changeset
1884 if (n % 2)
kono
parents:
diff changeset
1885 y = y * x;
kono
parents:
diff changeset
1886 }
kono
parents:
diff changeset
1887 return m < 0 ? 1/y : y;
kono
parents:
diff changeset
1888 }
kono
parents:
diff changeset
1889
kono
parents:
diff changeset
1890 #endif
kono
parents:
diff changeset
1891
kono
parents:
diff changeset
1892 #if((defined(L_mulhc3) || defined(L_divhc3)) && LIBGCC2_HAS_HF_MODE) \
kono
parents:
diff changeset
1893 || ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
kono
parents:
diff changeset
1894 || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
kono
parents:
diff changeset
1895 || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
kono
parents:
diff changeset
1896 || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE)
kono
parents:
diff changeset
1897
kono
parents:
diff changeset
1898 #undef float
kono
parents:
diff changeset
1899 #undef double
kono
parents:
diff changeset
1900 #undef long
kono
parents:
diff changeset
1901
kono
parents:
diff changeset
1902 #if defined(L_mulhc3) || defined(L_divhc3)
kono
parents:
diff changeset
1903 # define MTYPE HFtype
kono
parents:
diff changeset
1904 # define CTYPE HCtype
kono
parents:
diff changeset
1905 # define MODE hc
kono
parents:
diff changeset
1906 # define CEXT __LIBGCC_HF_FUNC_EXT__
kono
parents:
diff changeset
1907 # define NOTRUNC (!__LIBGCC_HF_EXCESS_PRECISION__)
kono
parents:
diff changeset
1908 #elif defined(L_mulsc3) || defined(L_divsc3)
kono
parents:
diff changeset
1909 # define MTYPE SFtype
kono
parents:
diff changeset
1910 # define CTYPE SCtype
kono
parents:
diff changeset
1911 # define MODE sc
kono
parents:
diff changeset
1912 # define CEXT __LIBGCC_SF_FUNC_EXT__
kono
parents:
diff changeset
1913 # define NOTRUNC (!__LIBGCC_SF_EXCESS_PRECISION__)
kono
parents:
diff changeset
1914 #elif defined(L_muldc3) || defined(L_divdc3)
kono
parents:
diff changeset
1915 # define MTYPE DFtype
kono
parents:
diff changeset
1916 # define CTYPE DCtype
kono
parents:
diff changeset
1917 # define MODE dc
kono
parents:
diff changeset
1918 # define CEXT __LIBGCC_DF_FUNC_EXT__
kono
parents:
diff changeset
1919 # define NOTRUNC (!__LIBGCC_DF_EXCESS_PRECISION__)
kono
parents:
diff changeset
1920 #elif defined(L_mulxc3) || defined(L_divxc3)
kono
parents:
diff changeset
1921 # define MTYPE XFtype
kono
parents:
diff changeset
1922 # define CTYPE XCtype
kono
parents:
diff changeset
1923 # define MODE xc
kono
parents:
diff changeset
1924 # define CEXT __LIBGCC_XF_FUNC_EXT__
kono
parents:
diff changeset
1925 # define NOTRUNC (!__LIBGCC_XF_EXCESS_PRECISION__)
kono
parents:
diff changeset
1926 #elif defined(L_multc3) || defined(L_divtc3)
kono
parents:
diff changeset
1927 # define MTYPE TFtype
kono
parents:
diff changeset
1928 # define CTYPE TCtype
kono
parents:
diff changeset
1929 # define MODE tc
kono
parents:
diff changeset
1930 # define CEXT __LIBGCC_TF_FUNC_EXT__
kono
parents:
diff changeset
1931 # define NOTRUNC (!__LIBGCC_TF_EXCESS_PRECISION__)
kono
parents:
diff changeset
1932 #else
kono
parents:
diff changeset
1933 # error
kono
parents:
diff changeset
1934 #endif
kono
parents:
diff changeset
1935
kono
parents:
diff changeset
1936 #define CONCAT3(A,B,C) _CONCAT3(A,B,C)
kono
parents:
diff changeset
1937 #define _CONCAT3(A,B,C) A##B##C
kono
parents:
diff changeset
1938
kono
parents:
diff changeset
1939 #define CONCAT2(A,B) _CONCAT2(A,B)
kono
parents:
diff changeset
1940 #define _CONCAT2(A,B) A##B
kono
parents:
diff changeset
1941
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1942 #define isnan(x) __builtin_isnan (x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1943 #define isfinite(x) __builtin_isfinite (x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1944 #define isinf(x) __builtin_isinf (x)
111
kono
parents:
diff changeset
1945
kono
parents:
diff changeset
1946 #define INFINITY CONCAT2(__builtin_huge_val, CEXT) ()
kono
parents:
diff changeset
1947 #define I 1i
kono
parents:
diff changeset
1948
kono
parents:
diff changeset
1949 /* Helpers to make the following code slightly less gross. */
kono
parents:
diff changeset
1950 #define COPYSIGN CONCAT2(__builtin_copysign, CEXT)
kono
parents:
diff changeset
1951 #define FABS CONCAT2(__builtin_fabs, CEXT)
kono
parents:
diff changeset
1952
kono
parents:
diff changeset
1953 /* Verify that MTYPE matches up with CEXT. */
kono
parents:
diff changeset
1954 extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
kono
parents:
diff changeset
1955
kono
parents:
diff changeset
1956 /* Ensure that we've lost any extra precision. */
kono
parents:
diff changeset
1957 #if NOTRUNC
kono
parents:
diff changeset
1958 # define TRUNC(x)
kono
parents:
diff changeset
1959 #else
kono
parents:
diff changeset
1960 # define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x))
kono
parents:
diff changeset
1961 #endif
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 #if defined(L_mulhc3) || defined(L_mulsc3) || defined(L_muldc3) \
kono
parents:
diff changeset
1964 || defined(L_mulxc3) || defined(L_multc3)
kono
parents:
diff changeset
1965
kono
parents:
diff changeset
1966 CTYPE
kono
parents:
diff changeset
1967 CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
kono
parents:
diff changeset
1968 {
kono
parents:
diff changeset
1969 MTYPE ac, bd, ad, bc, x, y;
kono
parents:
diff changeset
1970 CTYPE res;
kono
parents:
diff changeset
1971
kono
parents:
diff changeset
1972 ac = a * c;
kono
parents:
diff changeset
1973 bd = b * d;
kono
parents:
diff changeset
1974 ad = a * d;
kono
parents:
diff changeset
1975 bc = b * c;
kono
parents:
diff changeset
1976
kono
parents:
diff changeset
1977 TRUNC (ac);
kono
parents:
diff changeset
1978 TRUNC (bd);
kono
parents:
diff changeset
1979 TRUNC (ad);
kono
parents:
diff changeset
1980 TRUNC (bc);
kono
parents:
diff changeset
1981
kono
parents:
diff changeset
1982 x = ac - bd;
kono
parents:
diff changeset
1983 y = ad + bc;
kono
parents:
diff changeset
1984
kono
parents:
diff changeset
1985 if (isnan (x) && isnan (y))
kono
parents:
diff changeset
1986 {
kono
parents:
diff changeset
1987 /* Recover infinities that computed as NaN + iNaN. */
kono
parents:
diff changeset
1988 _Bool recalc = 0;
kono
parents:
diff changeset
1989 if (isinf (a) || isinf (b))
kono
parents:
diff changeset
1990 {
kono
parents:
diff changeset
1991 /* z is infinite. "Box" the infinity and change NaNs in
kono
parents:
diff changeset
1992 the other factor to 0. */
kono
parents:
diff changeset
1993 a = COPYSIGN (isinf (a) ? 1 : 0, a);
kono
parents:
diff changeset
1994 b = COPYSIGN (isinf (b) ? 1 : 0, b);
kono
parents:
diff changeset
1995 if (isnan (c)) c = COPYSIGN (0, c);
kono
parents:
diff changeset
1996 if (isnan (d)) d = COPYSIGN (0, d);
kono
parents:
diff changeset
1997 recalc = 1;
kono
parents:
diff changeset
1998 }
kono
parents:
diff changeset
1999 if (isinf (c) || isinf (d))
kono
parents:
diff changeset
2000 {
kono
parents:
diff changeset
2001 /* w is infinite. "Box" the infinity and change NaNs in
kono
parents:
diff changeset
2002 the other factor to 0. */
kono
parents:
diff changeset
2003 c = COPYSIGN (isinf (c) ? 1 : 0, c);
kono
parents:
diff changeset
2004 d = COPYSIGN (isinf (d) ? 1 : 0, d);
kono
parents:
diff changeset
2005 if (isnan (a)) a = COPYSIGN (0, a);
kono
parents:
diff changeset
2006 if (isnan (b)) b = COPYSIGN (0, b);
kono
parents:
diff changeset
2007 recalc = 1;
kono
parents:
diff changeset
2008 }
kono
parents:
diff changeset
2009 if (!recalc
kono
parents:
diff changeset
2010 && (isinf (ac) || isinf (bd)
kono
parents:
diff changeset
2011 || isinf (ad) || isinf (bc)))
kono
parents:
diff changeset
2012 {
kono
parents:
diff changeset
2013 /* Recover infinities from overflow by changing NaNs to 0. */
kono
parents:
diff changeset
2014 if (isnan (a)) a = COPYSIGN (0, a);
kono
parents:
diff changeset
2015 if (isnan (b)) b = COPYSIGN (0, b);
kono
parents:
diff changeset
2016 if (isnan (c)) c = COPYSIGN (0, c);
kono
parents:
diff changeset
2017 if (isnan (d)) d = COPYSIGN (0, d);
kono
parents:
diff changeset
2018 recalc = 1;
kono
parents:
diff changeset
2019 }
kono
parents:
diff changeset
2020 if (recalc)
kono
parents:
diff changeset
2021 {
kono
parents:
diff changeset
2022 x = INFINITY * (a * c - b * d);
kono
parents:
diff changeset
2023 y = INFINITY * (a * d + b * c);
kono
parents:
diff changeset
2024 }
kono
parents:
diff changeset
2025 }
kono
parents:
diff changeset
2026
kono
parents:
diff changeset
2027 __real__ res = x;
kono
parents:
diff changeset
2028 __imag__ res = y;
kono
parents:
diff changeset
2029 return res;
kono
parents:
diff changeset
2030 }
kono
parents:
diff changeset
2031 #endif /* complex multiply */
kono
parents:
diff changeset
2032
kono
parents:
diff changeset
2033 #if defined(L_divhc3) || defined(L_divsc3) || defined(L_divdc3) \
kono
parents:
diff changeset
2034 || defined(L_divxc3) || defined(L_divtc3)
kono
parents:
diff changeset
2035
kono
parents:
diff changeset
2036 CTYPE
kono
parents:
diff changeset
2037 CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
kono
parents:
diff changeset
2038 {
kono
parents:
diff changeset
2039 MTYPE denom, ratio, x, y;
kono
parents:
diff changeset
2040 CTYPE res;
kono
parents:
diff changeset
2041
kono
parents:
diff changeset
2042 /* ??? We can get better behavior from logarithmic scaling instead of
kono
parents:
diff changeset
2043 the division. But that would mean starting to link libgcc against
kono
parents:
diff changeset
2044 libm. We could implement something akin to ldexp/frexp as gcc builtins
kono
parents:
diff changeset
2045 fairly easily... */
kono
parents:
diff changeset
2046 if (FABS (c) < FABS (d))
kono
parents:
diff changeset
2047 {
kono
parents:
diff changeset
2048 ratio = c / d;
kono
parents:
diff changeset
2049 denom = (c * ratio) + d;
kono
parents:
diff changeset
2050 x = ((a * ratio) + b) / denom;
kono
parents:
diff changeset
2051 y = ((b * ratio) - a) / denom;
kono
parents:
diff changeset
2052 }
kono
parents:
diff changeset
2053 else
kono
parents:
diff changeset
2054 {
kono
parents:
diff changeset
2055 ratio = d / c;
kono
parents:
diff changeset
2056 denom = (d * ratio) + c;
kono
parents:
diff changeset
2057 x = ((b * ratio) + a) / denom;
kono
parents:
diff changeset
2058 y = (b - (a * ratio)) / denom;
kono
parents:
diff changeset
2059 }
kono
parents:
diff changeset
2060
kono
parents:
diff changeset
2061 /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
kono
parents:
diff changeset
2062 are nonzero/zero, infinite/finite, and finite/infinite. */
kono
parents:
diff changeset
2063 if (isnan (x) && isnan (y))
kono
parents:
diff changeset
2064 {
kono
parents:
diff changeset
2065 if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
kono
parents:
diff changeset
2066 {
kono
parents:
diff changeset
2067 x = COPYSIGN (INFINITY, c) * a;
kono
parents:
diff changeset
2068 y = COPYSIGN (INFINITY, c) * b;
kono
parents:
diff changeset
2069 }
kono
parents:
diff changeset
2070 else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
kono
parents:
diff changeset
2071 {
kono
parents:
diff changeset
2072 a = COPYSIGN (isinf (a) ? 1 : 0, a);
kono
parents:
diff changeset
2073 b = COPYSIGN (isinf (b) ? 1 : 0, b);
kono
parents:
diff changeset
2074 x = INFINITY * (a * c + b * d);
kono
parents:
diff changeset
2075 y = INFINITY * (b * c - a * d);
kono
parents:
diff changeset
2076 }
kono
parents:
diff changeset
2077 else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
kono
parents:
diff changeset
2078 {
kono
parents:
diff changeset
2079 c = COPYSIGN (isinf (c) ? 1 : 0, c);
kono
parents:
diff changeset
2080 d = COPYSIGN (isinf (d) ? 1 : 0, d);
kono
parents:
diff changeset
2081 x = 0.0 * (a * c + b * d);
kono
parents:
diff changeset
2082 y = 0.0 * (b * c - a * d);
kono
parents:
diff changeset
2083 }
kono
parents:
diff changeset
2084 }
kono
parents:
diff changeset
2085
kono
parents:
diff changeset
2086 __real__ res = x;
kono
parents:
diff changeset
2087 __imag__ res = y;
kono
parents:
diff changeset
2088 return res;
kono
parents:
diff changeset
2089 }
kono
parents:
diff changeset
2090 #endif /* complex divide */
kono
parents:
diff changeset
2091
kono
parents:
diff changeset
2092 #endif /* all complex float routines */
kono
parents:
diff changeset
2093
kono
parents:
diff changeset
2094 /* From here on down, the routines use normal data types. */
kono
parents:
diff changeset
2095
kono
parents:
diff changeset
2096 #define SItype bogus_type
kono
parents:
diff changeset
2097 #define USItype bogus_type
kono
parents:
diff changeset
2098 #define DItype bogus_type
kono
parents:
diff changeset
2099 #define UDItype bogus_type
kono
parents:
diff changeset
2100 #define SFtype bogus_type
kono
parents:
diff changeset
2101 #define DFtype bogus_type
kono
parents:
diff changeset
2102 #undef Wtype
kono
parents:
diff changeset
2103 #undef UWtype
kono
parents:
diff changeset
2104 #undef HWtype
kono
parents:
diff changeset
2105 #undef UHWtype
kono
parents:
diff changeset
2106 #undef DWtype
kono
parents:
diff changeset
2107 #undef UDWtype
kono
parents:
diff changeset
2108
kono
parents:
diff changeset
2109 #undef char
kono
parents:
diff changeset
2110 #undef short
kono
parents:
diff changeset
2111 #undef int
kono
parents:
diff changeset
2112 #undef long
kono
parents:
diff changeset
2113 #undef unsigned
kono
parents:
diff changeset
2114 #undef float
kono
parents:
diff changeset
2115 #undef double
kono
parents:
diff changeset
2116
kono
parents:
diff changeset
2117 #ifdef L__gcc_bcmp
kono
parents:
diff changeset
2118
kono
parents:
diff changeset
2119 /* Like bcmp except the sign is meaningful.
kono
parents:
diff changeset
2120 Result is negative if S1 is less than S2,
kono
parents:
diff changeset
2121 positive if S1 is greater, 0 if S1 and S2 are equal. */
kono
parents:
diff changeset
2122
kono
parents:
diff changeset
2123 int
kono
parents:
diff changeset
2124 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
kono
parents:
diff changeset
2125 {
kono
parents:
diff changeset
2126 while (size > 0)
kono
parents:
diff changeset
2127 {
kono
parents:
diff changeset
2128 const unsigned char c1 = *s1++, c2 = *s2++;
kono
parents:
diff changeset
2129 if (c1 != c2)
kono
parents:
diff changeset
2130 return c1 - c2;
kono
parents:
diff changeset
2131 size--;
kono
parents:
diff changeset
2132 }
kono
parents:
diff changeset
2133 return 0;
kono
parents:
diff changeset
2134 }
kono
parents:
diff changeset
2135
kono
parents:
diff changeset
2136 #endif
kono
parents:
diff changeset
2137
kono
parents:
diff changeset
2138 /* __eprintf used to be used by GCC's private version of <assert.h>.
kono
parents:
diff changeset
2139 We no longer provide that header, but this routine remains in libgcc.a
kono
parents:
diff changeset
2140 for binary backward compatibility. Note that it is not included in
kono
parents:
diff changeset
2141 the shared version of libgcc. */
kono
parents:
diff changeset
2142 #ifdef L_eprintf
kono
parents:
diff changeset
2143 #ifndef inhibit_libc
kono
parents:
diff changeset
2144
kono
parents:
diff changeset
2145 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
kono
parents:
diff changeset
2146 #include <stdio.h>
kono
parents:
diff changeset
2147
kono
parents:
diff changeset
2148 void
kono
parents:
diff changeset
2149 __eprintf (const char *string, const char *expression,
kono
parents:
diff changeset
2150 unsigned int line, const char *filename)
kono
parents:
diff changeset
2151 {
kono
parents:
diff changeset
2152 fprintf (stderr, string, expression, line, filename);
kono
parents:
diff changeset
2153 fflush (stderr);
kono
parents:
diff changeset
2154 abort ();
kono
parents:
diff changeset
2155 }
kono
parents:
diff changeset
2156
kono
parents:
diff changeset
2157 #endif
kono
parents:
diff changeset
2158 #endif
kono
parents:
diff changeset
2159
kono
parents:
diff changeset
2160
kono
parents:
diff changeset
2161 #ifdef L_clear_cache
kono
parents:
diff changeset
2162 /* Clear part of an instruction cache. */
kono
parents:
diff changeset
2163
kono
parents:
diff changeset
2164 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2165 __clear_cache (void *beg __attribute__((__unused__)),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2166 void *end __attribute__((__unused__)))
111
kono
parents:
diff changeset
2167 {
kono
parents:
diff changeset
2168 #ifdef CLEAR_INSN_CACHE
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2169 /* Cast the void* pointers to char* as some implementations
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2170 of the macro assume the pointers can be subtracted from
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2171 one another. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2172 CLEAR_INSN_CACHE ((char *) beg, (char *) end);
111
kono
parents:
diff changeset
2173 #endif /* CLEAR_INSN_CACHE */
kono
parents:
diff changeset
2174 }
kono
parents:
diff changeset
2175
kono
parents:
diff changeset
2176 #endif /* L_clear_cache */
kono
parents:
diff changeset
2177
kono
parents:
diff changeset
2178 #ifdef L_trampoline
kono
parents:
diff changeset
2179
kono
parents:
diff changeset
2180 /* Jump to a trampoline, loading the static chain address. */
kono
parents:
diff changeset
2181
kono
parents:
diff changeset
2182 #if defined(WINNT) && ! defined(__CYGWIN__)
kono
parents:
diff changeset
2183 #include <windows.h>
kono
parents:
diff changeset
2184 int getpagesize (void);
kono
parents:
diff changeset
2185 int mprotect (char *,int, int);
kono
parents:
diff changeset
2186
kono
parents:
diff changeset
2187 int
kono
parents:
diff changeset
2188 getpagesize (void)
kono
parents:
diff changeset
2189 {
kono
parents:
diff changeset
2190 #ifdef _ALPHA_
kono
parents:
diff changeset
2191 return 8192;
kono
parents:
diff changeset
2192 #else
kono
parents:
diff changeset
2193 return 4096;
kono
parents:
diff changeset
2194 #endif
kono
parents:
diff changeset
2195 }
kono
parents:
diff changeset
2196
kono
parents:
diff changeset
2197 int
kono
parents:
diff changeset
2198 mprotect (char *addr, int len, int prot)
kono
parents:
diff changeset
2199 {
kono
parents:
diff changeset
2200 DWORD np, op;
kono
parents:
diff changeset
2201
kono
parents:
diff changeset
2202 if (prot == 7)
kono
parents:
diff changeset
2203 np = 0x40;
kono
parents:
diff changeset
2204 else if (prot == 5)
kono
parents:
diff changeset
2205 np = 0x20;
kono
parents:
diff changeset
2206 else if (prot == 4)
kono
parents:
diff changeset
2207 np = 0x10;
kono
parents:
diff changeset
2208 else if (prot == 3)
kono
parents:
diff changeset
2209 np = 0x04;
kono
parents:
diff changeset
2210 else if (prot == 1)
kono
parents:
diff changeset
2211 np = 0x02;
kono
parents:
diff changeset
2212 else if (prot == 0)
kono
parents:
diff changeset
2213 np = 0x01;
kono
parents:
diff changeset
2214 else
kono
parents:
diff changeset
2215 return -1;
kono
parents:
diff changeset
2216
kono
parents:
diff changeset
2217 if (VirtualProtect (addr, len, np, &op))
kono
parents:
diff changeset
2218 return 0;
kono
parents:
diff changeset
2219 else
kono
parents:
diff changeset
2220 return -1;
kono
parents:
diff changeset
2221 }
kono
parents:
diff changeset
2222
kono
parents:
diff changeset
2223 #endif /* WINNT && ! __CYGWIN__ */
kono
parents:
diff changeset
2224
kono
parents:
diff changeset
2225 #ifdef TRANSFER_FROM_TRAMPOLINE
kono
parents:
diff changeset
2226 TRANSFER_FROM_TRAMPOLINE
kono
parents:
diff changeset
2227 #endif
kono
parents:
diff changeset
2228 #endif /* L_trampoline */
kono
parents:
diff changeset
2229
kono
parents:
diff changeset
2230 #ifndef __CYGWIN__
kono
parents:
diff changeset
2231 #ifdef L__main
kono
parents:
diff changeset
2232
kono
parents:
diff changeset
2233 #include "gbl-ctors.h"
kono
parents:
diff changeset
2234
kono
parents:
diff changeset
2235 /* Some systems use __main in a way incompatible with its use in gcc, in these
kono
parents:
diff changeset
2236 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
kono
parents:
diff changeset
2237 give the same symbol without quotes for an alternative entry point. You
kono
parents:
diff changeset
2238 must define both, or neither. */
kono
parents:
diff changeset
2239 #ifndef NAME__MAIN
kono
parents:
diff changeset
2240 #define NAME__MAIN "__main"
kono
parents:
diff changeset
2241 #define SYMBOL__MAIN __main
kono
parents:
diff changeset
2242 #endif
kono
parents:
diff changeset
2243
kono
parents:
diff changeset
2244 #if defined (__LIBGCC_INIT_SECTION_ASM_OP__) \
kono
parents:
diff changeset
2245 || defined (__LIBGCC_INIT_ARRAY_SECTION_ASM_OP__)
kono
parents:
diff changeset
2246 #undef HAS_INIT_SECTION
kono
parents:
diff changeset
2247 #define HAS_INIT_SECTION
kono
parents:
diff changeset
2248 #endif
kono
parents:
diff changeset
2249
kono
parents:
diff changeset
2250 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
kono
parents:
diff changeset
2251
kono
parents:
diff changeset
2252 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
kono
parents:
diff changeset
2253 code to run constructors. In that case, we need to handle EH here, too.
kono
parents:
diff changeset
2254 But MINGW32 is special because it handles CRTSTUFF and EH on its own. */
kono
parents:
diff changeset
2255
kono
parents:
diff changeset
2256 #ifdef __MINGW32__
kono
parents:
diff changeset
2257 #undef __LIBGCC_EH_FRAME_SECTION_NAME__
kono
parents:
diff changeset
2258 #endif
kono
parents:
diff changeset
2259
kono
parents:
diff changeset
2260 #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
kono
parents:
diff changeset
2261 #include "unwind-dw2-fde.h"
kono
parents:
diff changeset
2262 extern unsigned char __EH_FRAME_BEGIN__[];
kono
parents:
diff changeset
2263 #endif
kono
parents:
diff changeset
2264
kono
parents:
diff changeset
2265 /* Run all the global destructors on exit from the program. */
kono
parents:
diff changeset
2266
kono
parents:
diff changeset
2267 void
kono
parents:
diff changeset
2268 __do_global_dtors (void)
kono
parents:
diff changeset
2269 {
kono
parents:
diff changeset
2270 #ifdef DO_GLOBAL_DTORS_BODY
kono
parents:
diff changeset
2271 DO_GLOBAL_DTORS_BODY;
kono
parents:
diff changeset
2272 #else
kono
parents:
diff changeset
2273 static func_ptr *p = __DTOR_LIST__ + 1;
kono
parents:
diff changeset
2274 while (*p)
kono
parents:
diff changeset
2275 {
kono
parents:
diff changeset
2276 p++;
kono
parents:
diff changeset
2277 (*(p-1)) ();
kono
parents:
diff changeset
2278 }
kono
parents:
diff changeset
2279 #endif
kono
parents:
diff changeset
2280 #if defined (__LIBGCC_EH_FRAME_SECTION_NAME__) && !defined (HAS_INIT_SECTION)
kono
parents:
diff changeset
2281 {
kono
parents:
diff changeset
2282 static int completed = 0;
kono
parents:
diff changeset
2283 if (! completed)
kono
parents:
diff changeset
2284 {
kono
parents:
diff changeset
2285 completed = 1;
kono
parents:
diff changeset
2286 __deregister_frame_info (__EH_FRAME_BEGIN__);
kono
parents:
diff changeset
2287 }
kono
parents:
diff changeset
2288 }
kono
parents:
diff changeset
2289 #endif
kono
parents:
diff changeset
2290 }
kono
parents:
diff changeset
2291 #endif
kono
parents:
diff changeset
2292
kono
parents:
diff changeset
2293 #ifndef HAS_INIT_SECTION
kono
parents:
diff changeset
2294 /* Run all the global constructors on entry to the program. */
kono
parents:
diff changeset
2295
kono
parents:
diff changeset
2296 void
kono
parents:
diff changeset
2297 __do_global_ctors (void)
kono
parents:
diff changeset
2298 {
kono
parents:
diff changeset
2299 #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
kono
parents:
diff changeset
2300 {
kono
parents:
diff changeset
2301 static struct object object;
kono
parents:
diff changeset
2302 __register_frame_info (__EH_FRAME_BEGIN__, &object);
kono
parents:
diff changeset
2303 }
kono
parents:
diff changeset
2304 #endif
kono
parents:
diff changeset
2305 DO_GLOBAL_CTORS_BODY;
kono
parents:
diff changeset
2306 atexit (__do_global_dtors);
kono
parents:
diff changeset
2307 }
kono
parents:
diff changeset
2308 #endif /* no HAS_INIT_SECTION */
kono
parents:
diff changeset
2309
kono
parents:
diff changeset
2310 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
kono
parents:
diff changeset
2311 /* Subroutine called automatically by `main'.
kono
parents:
diff changeset
2312 Compiling a global function named `main'
kono
parents:
diff changeset
2313 produces an automatic call to this function at the beginning.
kono
parents:
diff changeset
2314
kono
parents:
diff changeset
2315 For many systems, this routine calls __do_global_ctors.
kono
parents:
diff changeset
2316 For systems which support a .init section we use the .init section
kono
parents:
diff changeset
2317 to run __do_global_ctors, so we need not do anything here. */
kono
parents:
diff changeset
2318
kono
parents:
diff changeset
2319 extern void SYMBOL__MAIN (void);
kono
parents:
diff changeset
2320 void
kono
parents:
diff changeset
2321 SYMBOL__MAIN (void)
kono
parents:
diff changeset
2322 {
kono
parents:
diff changeset
2323 /* Support recursive calls to `main': run initializers just once. */
kono
parents:
diff changeset
2324 static int initialized;
kono
parents:
diff changeset
2325 if (! initialized)
kono
parents:
diff changeset
2326 {
kono
parents:
diff changeset
2327 initialized = 1;
kono
parents:
diff changeset
2328 __do_global_ctors ();
kono
parents:
diff changeset
2329 }
kono
parents:
diff changeset
2330 }
kono
parents:
diff changeset
2331 #endif /* no HAS_INIT_SECTION or INVOKE__main */
kono
parents:
diff changeset
2332
kono
parents:
diff changeset
2333 #endif /* L__main */
kono
parents:
diff changeset
2334 #endif /* __CYGWIN__ */
kono
parents:
diff changeset
2335
kono
parents:
diff changeset
2336 #ifdef L_ctors
kono
parents:
diff changeset
2337
kono
parents:
diff changeset
2338 #include "gbl-ctors.h"
kono
parents:
diff changeset
2339
kono
parents:
diff changeset
2340 /* Provide default definitions for the lists of constructors and
kono
parents:
diff changeset
2341 destructors, so that we don't get linker errors. These symbols are
kono
parents:
diff changeset
2342 intentionally bss symbols, so that gld and/or collect will provide
kono
parents:
diff changeset
2343 the right values. */
kono
parents:
diff changeset
2344
kono
parents:
diff changeset
2345 /* We declare the lists here with two elements each,
kono
parents:
diff changeset
2346 so that they are valid empty lists if no other definition is loaded.
kono
parents:
diff changeset
2347
kono
parents:
diff changeset
2348 If we are using the old "set" extensions to have the gnu linker
kono
parents:
diff changeset
2349 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
kono
parents:
diff changeset
2350 must be in the bss/common section.
kono
parents:
diff changeset
2351
kono
parents:
diff changeset
2352 Long term no port should use those extensions. But many still do. */
kono
parents:
diff changeset
2353 #if !defined(__LIBGCC_INIT_SECTION_ASM_OP__)
kono
parents:
diff changeset
2354 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
kono
parents:
diff changeset
2355 func_ptr __CTOR_LIST__[2] = {0, 0};
kono
parents:
diff changeset
2356 func_ptr __DTOR_LIST__[2] = {0, 0};
kono
parents:
diff changeset
2357 #else
kono
parents:
diff changeset
2358 func_ptr __CTOR_LIST__[2];
kono
parents:
diff changeset
2359 func_ptr __DTOR_LIST__[2];
kono
parents:
diff changeset
2360 #endif
kono
parents:
diff changeset
2361 #endif /* no __LIBGCC_INIT_SECTION_ASM_OP__ */
kono
parents:
diff changeset
2362 #endif /* L_ctors */
kono
parents:
diff changeset
2363 #endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */