]>
Commit | Line | Data |
---|---|---|
62c63f32 | 1 | /* More subroutines needed by GCC output code on some machines. */ |
2 | /* Compile this one with gcc. */ | |
7429c938 | 3 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
08332e03 | 4 | 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
62c63f32 | 5 | |
f12b58b3 | 6 | This file is part of GCC. |
62c63f32 | 7 | |
f12b58b3 | 8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free | |
10 | Software Foundation; either version 2, or (at your option) any later | |
11 | version. | |
62c63f32 | 12 | |
4c9b6e71 | 13 | In addition to the permissions in the GNU General Public License, the |
14 | Free Software Foundation gives you unlimited permission to link the | |
15 | compiled version of this file into combinations with other programs, | |
16 | and to distribute those combinations without any restriction coming | |
17 | from the use of this file. (The General Public License restrictions | |
18 | do apply in other respects; for example, they cover modification of | |
19 | the file, and distribution when not linked into a combine | |
20 | executable.) | |
21 | ||
f12b58b3 | 22 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
23 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
24 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
25 | for more details. | |
62c63f32 | 26 | |
27 | You should have received a copy of the GNU General Public License | |
f12b58b3 | 28 | along with GCC; see the file COPYING. If not, write to the Free |
29 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
30 | 02111-1307, USA. */ | |
62c63f32 | 31 | |
395d450a | 32 | |
33 | /* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is | |
34 | supposedly valid even though this is a "target" file. */ | |
35 | #include "auto-host.h" | |
36 | ||
62c63f32 | 37 | /* It is incorrect to include config.h here, because this file is being |
38 | compiled for the target, and hence definitions concerning only the host | |
39 | do not apply. */ | |
c538053c | 40 | #include "tconfig.h" |
069631e1 | 41 | #include "tsystem.h" |
805e22b2 | 42 | #include "coretypes.h" |
43 | #include "tm.h" | |
8c304688 | 44 | |
62c63f32 | 45 | /* Don't use `fancy_abort' here even if config.h says to use it. */ |
46 | #ifdef abort | |
47 | #undef abort | |
48 | #endif | |
49 | ||
395d450a | 50 | #ifdef HAVE_GAS_HIDDEN |
51 | #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) | |
52 | #else | |
53 | #define ATTRIBUTE_HIDDEN | |
54 | #endif | |
55 | ||
b1e341a2 | 56 | #include "libgcc2.h" |
62c63f32 | 57 | \f |
856ba90e | 58 | #ifdef DECLARE_LIBRARY_RENAMES |
59 | DECLARE_LIBRARY_RENAMES | |
60 | #endif | |
61 | ||
f4dbfb4e | 62 | #if defined (L_negdi2) |
e40ae714 | 63 | DWtype |
64 | __negdi2 (DWtype u) | |
65 | { | |
ec7f942b | 66 | const DWunion uu = {.ll = u}; |
67 | const DWunion w = { {.low = -uu.s.low, | |
68 | .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } }; | |
e40ae714 | 69 | |
70 | return w.ll; | |
71 | } | |
72 | #endif | |
bec2d490 | 73 | |
74 | #ifdef L_addvsi3 | |
578dc367 | 75 | Wtype |
ad7a5867 | 76 | __addvSI3 (Wtype a, Wtype b) |
bec2d490 | 77 | { |
ec7f942b | 78 | const Wtype w = a + b; |
bec2d490 | 79 | |
80 | if (b >= 0 ? w < a : w > a) | |
81 | abort (); | |
82 | ||
83 | return w; | |
87e97de6 | 84 | } |
ad7a5867 | 85 | #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC |
86 | SItype | |
87 | __addvsi3 (SItype a, SItype b) | |
88 | { | |
89 | const SItype w = a + b; | |
90 | ||
91 | if (b >= 0 ? w < a : w > a) | |
92 | abort (); | |
93 | ||
94 | return w; | |
95 | } | |
96 | #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ | |
e40ae714 | 97 | #endif |
bec2d490 | 98 | \f |
99 | #ifdef L_addvdi3 | |
578dc367 | 100 | DWtype |
ad7a5867 | 101 | __addvDI3 (DWtype a, DWtype b) |
bec2d490 | 102 | { |
ec7f942b | 103 | const DWtype w = a + b; |
bec2d490 | 104 | |
105 | if (b >= 0 ? w < a : w > a) | |
106 | abort (); | |
107 | ||
108 | return w; | |
109 | } | |
110 | #endif | |
111 | \f | |
112 | #ifdef L_subvsi3 | |
578dc367 | 113 | Wtype |
ad7a5867 | 114 | __subvSI3 (Wtype a, Wtype b) |
bec2d490 | 115 | { |
ad7a5867 | 116 | const Wtype w = a - b; |
bec2d490 | 117 | |
118 | if (b >= 0 ? w > a : w < a) | |
119 | abort (); | |
120 | ||
121 | return w; | |
bec2d490 | 122 | } |
ad7a5867 | 123 | #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC |
124 | SItype | |
125 | __subvsi3 (SItype a, SItype b) | |
126 | { | |
127 | const SItype w = a - b; | |
128 | ||
129 | if (b >= 0 ? w > a : w < a) | |
130 | abort (); | |
131 | ||
132 | return w; | |
133 | } | |
134 | #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ | |
bec2d490 | 135 | #endif |
136 | \f | |
137 | #ifdef L_subvdi3 | |
578dc367 | 138 | DWtype |
ad7a5867 | 139 | __subvDI3 (DWtype a, DWtype b) |
bec2d490 | 140 | { |
ec7f942b | 141 | const DWtype w = a - b; |
bec2d490 | 142 | |
143 | if (b >= 0 ? w > a : w < a) | |
144 | abort (); | |
145 | ||
146 | return w; | |
bec2d490 | 147 | } |
148 | #endif | |
149 | \f | |
150 | #ifdef L_mulvsi3 | |
4772072d | 151 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
578dc367 | 152 | Wtype |
ad7a5867 | 153 | __mulvSI3 (Wtype a, Wtype b) |
bec2d490 | 154 | { |
ec7f942b | 155 | const DWtype w = (DWtype) a * (DWtype) b; |
bec2d490 | 156 | |
0cf3a1b4 | 157 | if ((Wtype) (w >> WORD_SIZE) != (Wtype) w >> (WORD_SIZE - 1)) |
bec2d490 | 158 | abort (); |
159 | ||
160 | return w; | |
161 | } | |
ad7a5867 | 162 | #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC |
163 | #undef WORD_SIZE | |
164 | #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) | |
165 | SItype | |
166 | __mulvsi3 (SItype a, SItype b) | |
167 | { | |
168 | const DItype w = (DItype) a * (DItype) b; | |
169 | ||
170 | if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1)) | |
171 | abort (); | |
172 | ||
173 | return w; | |
174 | } | |
175 | #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ | |
bec2d490 | 176 | #endif |
177 | \f | |
178 | #ifdef L_negvsi2 | |
578dc367 | 179 | Wtype |
ad7a5867 | 180 | __negvSI2 (Wtype a) |
bec2d490 | 181 | { |
ec7f942b | 182 | const Wtype w = -a; |
bec2d490 | 183 | |
184 | if (a >= 0 ? w > 0 : w < 0) | |
185 | abort (); | |
186 | ||
187 | return w; | |
188 | } | |
ad7a5867 | 189 | #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC |
190 | SItype | |
191 | __negvsi2 (SItype a) | |
192 | { | |
193 | const SItype w = -a; | |
194 | ||
195 | if (a >= 0 ? w > 0 : w < 0) | |
196 | abort (); | |
197 | ||
198 | return w; | |
199 | } | |
200 | #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ | |
bec2d490 | 201 | #endif |
202 | \f | |
203 | #ifdef L_negvdi2 | |
578dc367 | 204 | DWtype |
ad7a5867 | 205 | __negvDI2 (DWtype a) |
bec2d490 | 206 | { |
ec7f942b | 207 | const DWtype w = -a; |
bec2d490 | 208 | |
209 | if (a >= 0 ? w > 0 : w < 0) | |
210 | abort (); | |
211 | ||
8851e806 | 212 | return w; |
bec2d490 | 213 | } |
214 | #endif | |
215 | \f | |
216 | #ifdef L_absvsi2 | |
578dc367 | 217 | Wtype |
ad7a5867 | 218 | __absvSI2 (Wtype a) |
bec2d490 | 219 | { |
8851e806 | 220 | Wtype w = a; |
bec2d490 | 221 | |
ad7a5867 | 222 | if (a < 0) |
223 | #ifdef L_negvsi2 | |
224 | w = __negvSI2 (a); | |
225 | #else | |
226 | w = -a; | |
227 | ||
228 | if (w < 0) | |
229 | abort (); | |
230 | #endif | |
231 | ||
232 | return w; | |
233 | } | |
234 | #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC | |
235 | SItype | |
236 | __absvsi2 (SItype a) | |
237 | { | |
238 | SItype w = a; | |
239 | ||
8851e806 | 240 | if (a < 0) |
bec2d490 | 241 | #ifdef L_negvsi2 |
8851e806 | 242 | w = __negvsi2 (a); |
bec2d490 | 243 | #else |
8851e806 | 244 | w = -a; |
bec2d490 | 245 | |
8851e806 | 246 | if (w < 0) |
247 | abort (); | |
bec2d490 | 248 | #endif |
249 | ||
250 | return w; | |
251 | } | |
ad7a5867 | 252 | #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ |
bec2d490 | 253 | #endif |
254 | \f | |
255 | #ifdef L_absvdi2 | |
578dc367 | 256 | DWtype |
ad7a5867 | 257 | __absvDI2 (DWtype a) |
bec2d490 | 258 | { |
8851e806 | 259 | DWtype w = a; |
bec2d490 | 260 | |
8851e806 | 261 | if (a < 0) |
4772072d | 262 | #ifdef L_negvdi2 |
ad7a5867 | 263 | w = __negvDI2 (a); |
bec2d490 | 264 | #else |
8851e806 | 265 | w = -a; |
bec2d490 | 266 | |
8851e806 | 267 | if (w < 0) |
268 | abort (); | |
bec2d490 | 269 | #endif |
270 | ||
8851e806 | 271 | return w; |
bec2d490 | 272 | } |
273 | #endif | |
274 | \f | |
275 | #ifdef L_mulvdi3 | |
4772072d | 276 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
578dc367 | 277 | DWtype |
ad7a5867 | 278 | __mulvDI3 (DWtype u, DWtype v) |
bec2d490 | 279 | { |
4772072d | 280 | /* The unchecked multiplication needs 3 Wtype x Wtype multiplications, |
281 | but the checked multiplication needs only two. */ | |
ec7f942b | 282 | const DWunion uu = {.ll = u}; |
283 | const DWunion vv = {.ll = v}; | |
bec2d490 | 284 | |
4772072d | 285 | if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1)) |
286 | { | |
287 | /* u fits in a single Wtype. */ | |
288 | if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) | |
289 | { | |
290 | /* v fits in a single Wtype as well. */ | |
291 | /* A single multiplication. No overflow risk. */ | |
292 | return (DWtype) uu.s.low * (DWtype) vv.s.low; | |
293 | } | |
294 | else | |
295 | { | |
296 | /* Two multiplications. */ | |
ec7f942b | 297 | DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low |
298 | * (UDWtype) (UWtype) vv.s.low}; | |
299 | DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low | |
300 | * (UDWtype) (UWtype) vv.s.high}; | |
4772072d | 301 | |
4772072d | 302 | if (vv.s.high < 0) |
303 | w1.s.high -= uu.s.low; | |
304 | if (uu.s.low < 0) | |
305 | w1.ll -= vv.ll; | |
306 | w1.ll += (UWtype) w0.s.high; | |
307 | if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) | |
308 | { | |
309 | w0.s.high = w1.s.low; | |
310 | return w0.ll; | |
311 | } | |
312 | } | |
313 | } | |
314 | else | |
315 | { | |
316 | if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) | |
317 | { | |
318 | /* v fits into a single Wtype. */ | |
319 | /* Two multiplications. */ | |
ec7f942b | 320 | DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low |
321 | * (UDWtype) (UWtype) vv.s.low}; | |
322 | DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high | |
323 | * (UDWtype) (UWtype) vv.s.low}; | |
4772072d | 324 | |
4772072d | 325 | if (uu.s.high < 0) |
326 | w1.s.high -= vv.s.low; | |
327 | if (vv.s.low < 0) | |
328 | w1.ll -= uu.ll; | |
329 | w1.ll += (UWtype) w0.s.high; | |
330 | if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) | |
331 | { | |
332 | w0.s.high = w1.s.low; | |
333 | return w0.ll; | |
334 | } | |
335 | } | |
336 | else | |
337 | { | |
338 | /* A few sign checks and a single multiplication. */ | |
339 | if (uu.s.high >= 0) | |
340 | { | |
341 | if (vv.s.high >= 0) | |
342 | { | |
343 | if (uu.s.high == 0 && vv.s.high == 0) | |
344 | { | |
ec7f942b | 345 | const DWtype w = (UDWtype) (UWtype) uu.s.low |
346 | * (UDWtype) (UWtype) vv.s.low; | |
4772072d | 347 | if (__builtin_expect (w >= 0, 1)) |
348 | return w; | |
349 | } | |
350 | } | |
351 | else | |
352 | { | |
353 | if (uu.s.high == 0 && vv.s.high == (Wtype) -1) | |
354 | { | |
ec7f942b | 355 | DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low |
356 | * (UDWtype) (UWtype) vv.s.low}; | |
4772072d | 357 | |
4772072d | 358 | ww.s.high -= uu.s.low; |
359 | if (__builtin_expect (ww.s.high < 0, 1)) | |
360 | return ww.ll; | |
361 | } | |
362 | } | |
363 | } | |
364 | else | |
365 | { | |
366 | if (vv.s.high >= 0) | |
367 | { | |
368 | if (uu.s.high == (Wtype) -1 && vv.s.high == 0) | |
369 | { | |
ec7f942b | 370 | DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low |
371 | * (UDWtype) (UWtype) vv.s.low}; | |
4772072d | 372 | |
4772072d | 373 | ww.s.high -= vv.s.low; |
374 | if (__builtin_expect (ww.s.high < 0, 1)) | |
375 | return ww.ll; | |
376 | } | |
377 | } | |
378 | else | |
379 | { | |
380 | if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1) | |
381 | { | |
ec7f942b | 382 | DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low |
383 | * (UDWtype) (UWtype) vv.s.low}; | |
4772072d | 384 | |
4772072d | 385 | ww.s.high -= uu.s.low; |
386 | ww.s.high -= vv.s.low; | |
387 | if (__builtin_expect (ww.s.high >= 0, 1)) | |
388 | return ww.ll; | |
389 | } | |
390 | } | |
391 | } | |
392 | } | |
393 | } | |
bec2d490 | 394 | |
4772072d | 395 | /* Overflow. */ |
396 | abort (); | |
bec2d490 | 397 | } |
398 | #endif | |
399 | \f | |
62c63f32 | 400 | |
b903337a | 401 | /* Unless shift functions are defined with full ANSI prototypes, |
4f195a89 | 402 | parameter b will be promoted to int if word_type is smaller than an int. */ |
62c63f32 | 403 | #ifdef L_lshrdi3 |
cf378360 | 404 | DWtype |
405 | __lshrdi3 (DWtype u, word_type b) | |
62c63f32 | 406 | { |
62c63f32 | 407 | if (b == 0) |
408 | return u; | |
409 | ||
ec7f942b | 410 | const DWunion uu = {.ll = u}; |
411 | const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; | |
412 | DWunion w; | |
62c63f32 | 413 | |
62c63f32 | 414 | if (bm <= 0) |
415 | { | |
416 | w.s.high = 0; | |
d1138980 | 417 | w.s.low = (UWtype) uu.s.high >> -bm; |
62c63f32 | 418 | } |
419 | else | |
420 | { | |
ec7f942b | 421 | const UWtype carries = (UWtype) uu.s.high << bm; |
d1138980 | 422 | |
423 | w.s.high = (UWtype) uu.s.high >> b; | |
424 | w.s.low = ((UWtype) uu.s.low >> b) | carries; | |
62c63f32 | 425 | } |
426 | ||
427 | return w.ll; | |
428 | } | |
429 | #endif | |
430 | ||
431 | #ifdef L_ashldi3 | |
cf378360 | 432 | DWtype |
433 | __ashldi3 (DWtype u, word_type b) | |
62c63f32 | 434 | { |
62c63f32 | 435 | if (b == 0) |
436 | return u; | |
437 | ||
ec7f942b | 438 | const DWunion uu = {.ll = u}; |
439 | const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; | |
440 | DWunion w; | |
62c63f32 | 441 | |
62c63f32 | 442 | if (bm <= 0) |
443 | { | |
444 | w.s.low = 0; | |
d1138980 | 445 | w.s.high = (UWtype) uu.s.low << -bm; |
62c63f32 | 446 | } |
447 | else | |
448 | { | |
ec7f942b | 449 | const UWtype carries = (UWtype) uu.s.low >> bm; |
d1138980 | 450 | |
451 | w.s.low = (UWtype) uu.s.low << b; | |
452 | w.s.high = ((UWtype) uu.s.high << b) | carries; | |
62c63f32 | 453 | } |
454 | ||
455 | return w.ll; | |
456 | } | |
457 | #endif | |
458 | ||
459 | #ifdef L_ashrdi3 | |
cf378360 | 460 | DWtype |
461 | __ashrdi3 (DWtype u, word_type b) | |
62c63f32 | 462 | { |
62c63f32 | 463 | if (b == 0) |
464 | return u; | |
465 | ||
ec7f942b | 466 | const DWunion uu = {.ll = u}; |
467 | const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; | |
468 | DWunion w; | |
62c63f32 | 469 | |
62c63f32 | 470 | if (bm <= 0) |
471 | { | |
472 | /* w.s.high = 1..1 or 0..0 */ | |
cf378360 | 473 | w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1); |
62c63f32 | 474 | w.s.low = uu.s.high >> -bm; |
475 | } | |
476 | else | |
477 | { | |
ec7f942b | 478 | const UWtype carries = (UWtype) uu.s.high << bm; |
d1138980 | 479 | |
62c63f32 | 480 | w.s.high = uu.s.high >> b; |
d1138980 | 481 | w.s.low = ((UWtype) uu.s.low >> b) | carries; |
62c63f32 | 482 | } |
483 | ||
484 | return w.ll; | |
485 | } | |
486 | #endif | |
487 | \f | |
092445b3 | 488 | #ifdef L_ffssi2 |
489 | #undef int | |
092445b3 | 490 | int |
491 | __ffsSI2 (UWtype u) | |
492 | { | |
493 | UWtype count; | |
494 | ||
495 | if (u == 0) | |
496 | return 0; | |
497 | ||
498 | count_trailing_zeros (count, u); | |
499 | return count + 1; | |
500 | } | |
501 | #endif | |
502 | \f | |
5e4e1583 | 503 | #ifdef L_ffsdi2 |
7a02b4da | 504 | #undef int |
7a02b4da | 505 | int |
092445b3 | 506 | __ffsDI2 (DWtype u) |
5e4e1583 | 507 | { |
ec7f942b | 508 | const DWunion uu = {.ll = u}; |
9ce1b52b | 509 | UWtype word, count, add; |
510 | ||
9ce1b52b | 511 | if (uu.s.low != 0) |
512 | word = uu.s.low, add = 0; | |
513 | else if (uu.s.high != 0) | |
514 | word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype); | |
515 | else | |
516 | return 0; | |
517 | ||
518 | count_trailing_zeros (count, word); | |
519 | return count + add + 1; | |
5e4e1583 | 520 | } |
521 | #endif | |
522 | \f | |
62c63f32 | 523 | #ifdef L_muldi3 |
cf378360 | 524 | DWtype |
525 | __muldi3 (DWtype u, DWtype v) | |
62c63f32 | 526 | { |
ec7f942b | 527 | const DWunion uu = {.ll = u}; |
528 | const DWunion vv = {.ll = v}; | |
529 | DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; | |
62c63f32 | 530 | |
cf378360 | 531 | w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high |
532 | + (UWtype) uu.s.high * (UWtype) vv.s.low); | |
62c63f32 | 533 | |
534 | return w.ll; | |
535 | } | |
536 | #endif | |
537 | \f | |
1b3950b9 | 538 | #if (defined (L_udivdi3) || defined (L_divdi3) || \ |
539 | defined (L_umoddi3) || defined (L_moddi3)) | |
6b9d1b54 | 540 | #if defined (sdiv_qrnnd) |
1b3950b9 | 541 | #define L_udiv_w_sdiv |
542 | #endif | |
6b9d1b54 | 543 | #endif |
1b3950b9 | 544 | |
a46ef09f | 545 | #ifdef L_udiv_w_sdiv |
b10877f3 | 546 | #if defined (sdiv_qrnnd) |
1b3950b9 | 547 | #if (defined (L_udivdi3) || defined (L_divdi3) || \ |
548 | defined (L_umoddi3) || defined (L_moddi3)) | |
9dae5ac3 | 549 | static inline __attribute__ ((__always_inline__)) |
1b3950b9 | 550 | #endif |
cf378360 | 551 | UWtype |
552 | __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) | |
ba628a68 | 553 | { |
cf378360 | 554 | UWtype q, r; |
555 | UWtype c0, c1, b1; | |
ba628a68 | 556 | |
cf378360 | 557 | if ((Wtype) d >= 0) |
ba628a68 | 558 | { |
cf378360 | 559 | if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) |
ba628a68 | 560 | { |
778ac06a | 561 | /* Dividend, divisor, and quotient are nonnegative. */ |
ba628a68 | 562 | sdiv_qrnnd (q, r, a1, a0, d); |
563 | } | |
564 | else | |
565 | { | |
778ac06a | 566 | /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */ |
cf378360 | 567 | sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); |
778ac06a | 568 | /* Divide (c1*2^32 + c0) by d. */ |
ba628a68 | 569 | sdiv_qrnnd (q, r, c1, c0, d); |
778ac06a | 570 | /* Add 2^31 to quotient. */ |
cf378360 | 571 | q += (UWtype) 1 << (W_TYPE_SIZE - 1); |
ba628a68 | 572 | } |
573 | } | |
574 | else | |
575 | { | |
576 | b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ | |
577 | c1 = a1 >> 1; /* A/2 */ | |
cf378360 | 578 | c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); |
ba628a68 | 579 | |
580 | if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ | |
581 | { | |
582 | sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ | |
583 | ||
584 | r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ | |
585 | if ((d & 1) != 0) | |
586 | { | |
587 | if (r >= q) | |
588 | r = r - q; | |
589 | else if (q - r <= d) | |
590 | { | |
591 | r = r - q + d; | |
592 | q--; | |
593 | } | |
594 | else | |
595 | { | |
596 | r = r - q + 2*d; | |
597 | q -= 2; | |
598 | } | |
599 | } | |
600 | } | |
601 | else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ | |
602 | { | |
603 | c1 = (b1 - 1) - c1; | |
604 | c0 = ~c0; /* logical NOT */ | |
605 | ||
606 | sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ | |
607 | ||
608 | q = ~q; /* (A/2)/b1 */ | |
609 | r = (b1 - 1) - r; | |
610 | ||
611 | r = 2*r + (a0 & 1); /* A/(2*b1) */ | |
612 | ||
613 | if ((d & 1) != 0) | |
614 | { | |
615 | if (r >= q) | |
616 | r = r - q; | |
617 | else if (q - r <= d) | |
618 | { | |
619 | r = r - q + d; | |
620 | q--; | |
621 | } | |
622 | else | |
623 | { | |
624 | r = r - q + 2*d; | |
625 | q -= 2; | |
626 | } | |
627 | } | |
628 | } | |
629 | else /* Implies c1 = b1 */ | |
630 | { /* Hence a1 = d - 1 = 2*b1 - 1 */ | |
631 | if (a0 >= -d) | |
632 | { | |
633 | q = -1; | |
634 | r = a0 + d; | |
635 | } | |
636 | else | |
637 | { | |
638 | q = -2; | |
639 | r = a0 + 2*d; | |
640 | } | |
641 | } | |
642 | } | |
643 | ||
644 | *rp = r; | |
645 | return q; | |
646 | } | |
b10877f3 | 647 | #else |
648 | /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ | |
cf378360 | 649 | UWtype |
650 | __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), | |
651 | UWtype a1 __attribute__ ((__unused__)), | |
652 | UWtype a0 __attribute__ ((__unused__)), | |
653 | UWtype d __attribute__ ((__unused__))) | |
73439ee0 | 654 | { |
655 | return 0; | |
656 | } | |
b10877f3 | 657 | #endif |
ba628a68 | 658 | #endif |
659 | \f | |
a47053cf | 660 | #if (defined (L_udivdi3) || defined (L_divdi3) || \ |
661 | defined (L_umoddi3) || defined (L_moddi3)) | |
662 | #define L_udivmoddi4 | |
663 | #endif | |
664 | ||
9ce1b52b | 665 | #ifdef L_clz |
666 | const UQItype __clz_tab[] = | |
62c63f32 | 667 | { |
668 | 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, | |
669 | 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, | |
670 | 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, | |
671 | 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, | |
672 | 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, | |
673 | 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, | |
674 | 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, | |
675 | 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, | |
676 | }; | |
9ce1b52b | 677 | #endif |
6a08d0ab | 678 | \f |
679 | #ifdef L_clzsi2 | |
7a02b4da | 680 | #undef int |
7a02b4da | 681 | int |
0f186426 | 682 | __clzSI2 (UWtype x) |
6a08d0ab | 683 | { |
395d450a | 684 | Wtype ret; |
6a08d0ab | 685 | |
0f186426 | 686 | count_leading_zeros (ret, x); |
395d450a | 687 | |
688 | return ret; | |
6a08d0ab | 689 | } |
690 | #endif | |
691 | \f | |
692 | #ifdef L_clzdi2 | |
7a02b4da | 693 | #undef int |
7a02b4da | 694 | int |
0f186426 | 695 | __clzDI2 (UDWtype x) |
6a08d0ab | 696 | { |
ec7f942b | 697 | const DWunion uu = {.ll = x}; |
395d450a | 698 | UWtype word; |
699 | Wtype ret, add; | |
700 | ||
0f186426 | 701 | if (uu.s.high) |
702 | word = uu.s.high, add = 0; | |
395d450a | 703 | else |
0f186426 | 704 | word = uu.s.low, add = W_TYPE_SIZE; |
6a08d0ab | 705 | |
395d450a | 706 | count_leading_zeros (ret, word); |
707 | return ret + add; | |
6a08d0ab | 708 | } |
709 | #endif | |
710 | \f | |
711 | #ifdef L_ctzsi2 | |
7a02b4da | 712 | #undef int |
7a02b4da | 713 | int |
0f186426 | 714 | __ctzSI2 (UWtype x) |
6a08d0ab | 715 | { |
395d450a | 716 | Wtype ret; |
6a08d0ab | 717 | |
395d450a | 718 | count_trailing_zeros (ret, x); |
6a08d0ab | 719 | |
395d450a | 720 | return ret; |
6a08d0ab | 721 | } |
722 | #endif | |
723 | \f | |
724 | #ifdef L_ctzdi2 | |
7a02b4da | 725 | #undef int |
7a02b4da | 726 | int |
0f186426 | 727 | __ctzDI2 (UDWtype x) |
6a08d0ab | 728 | { |
ec7f942b | 729 | const DWunion uu = {.ll = x}; |
395d450a | 730 | UWtype word; |
731 | Wtype ret, add; | |
732 | ||
0f186426 | 733 | if (uu.s.low) |
734 | word = uu.s.low, add = 0; | |
395d450a | 735 | else |
0f186426 | 736 | word = uu.s.high, add = W_TYPE_SIZE; |
6a08d0ab | 737 | |
395d450a | 738 | count_trailing_zeros (ret, word); |
739 | return ret + add; | |
6a08d0ab | 740 | } |
741 | #endif | |
742 | ||
395d450a | 743 | #if (defined (L_popcountsi2) || defined (L_popcountdi2) \ |
744 | || defined (L_popcount_tab)) | |
745 | extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN; | |
6a08d0ab | 746 | #endif |
747 | ||
748 | #ifdef L_popcount_tab | |
749 | const UQItype __popcount_tab[] = | |
750 | { | |
751 | 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, | |
752 | 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, | |
753 | 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, | |
754 | 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, | |
755 | 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, | |
756 | 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, | |
757 | 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, | |
758 | 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, | |
759 | }; | |
760 | #endif | |
761 | \f | |
762 | #ifdef L_popcountsi2 | |
7a02b4da | 763 | #undef int |
7a02b4da | 764 | int |
0f186426 | 765 | __popcountSI2 (UWtype x) |
6a08d0ab | 766 | { |
0f186426 | 767 | UWtype i, ret = 0; |
768 | ||
769 | for (i = 0; i < W_TYPE_SIZE; i += 8) | |
770 | ret += __popcount_tab[(x >> i) & 0xff]; | |
771 | ||
772 | return ret; | |
6a08d0ab | 773 | } |
774 | #endif | |
775 | \f | |
776 | #ifdef L_popcountdi2 | |
7a02b4da | 777 | #undef int |
7a02b4da | 778 | int |
0f186426 | 779 | __popcountDI2 (UDWtype x) |
6a08d0ab | 780 | { |
0f186426 | 781 | UWtype i, ret = 0; |
782 | ||
783 | for (i = 0; i < 2*W_TYPE_SIZE; i += 8) | |
784 | ret += __popcount_tab[(x >> i) & 0xff]; | |
785 | ||
786 | return ret; | |
6a08d0ab | 787 | } |
788 | #endif | |
789 | \f | |
790 | #ifdef L_paritysi2 | |
7a02b4da | 791 | #undef int |
7a02b4da | 792 | int |
0f186426 | 793 | __paritySI2 (UWtype x) |
6a08d0ab | 794 | { |
0f186426 | 795 | #if W_TYPE_SIZE > 64 |
796 | # error "fill out the table" | |
797 | #endif | |
798 | #if W_TYPE_SIZE > 32 | |
799 | x ^= x >> 32; | |
800 | #endif | |
801 | #if W_TYPE_SIZE > 16 | |
802 | x ^= x >> 16; | |
803 | #endif | |
804 | x ^= x >> 8; | |
805 | x ^= x >> 4; | |
806 | x &= 0xf; | |
807 | return (0x6996 >> x) & 1; | |
6a08d0ab | 808 | } |
809 | #endif | |
810 | \f | |
811 | #ifdef L_paritydi2 | |
7a02b4da | 812 | #undef int |
7a02b4da | 813 | int |
0f186426 | 814 | __parityDI2 (UDWtype x) |
6a08d0ab | 815 | { |
ec7f942b | 816 | const DWunion uu = {.ll = x}; |
817 | UWtype nx = uu.s.low ^ uu.s.high; | |
0f186426 | 818 | |
819 | #if W_TYPE_SIZE > 64 | |
820 | # error "fill out the table" | |
821 | #endif | |
822 | #if W_TYPE_SIZE > 32 | |
823 | nx ^= nx >> 32; | |
824 | #endif | |
825 | #if W_TYPE_SIZE > 16 | |
6a08d0ab | 826 | nx ^= nx >> 16; |
0f186426 | 827 | #endif |
6a08d0ab | 828 | nx ^= nx >> 8; |
395d450a | 829 | nx ^= nx >> 4; |
9acebba8 | 830 | nx &= 0xf; |
831 | return (0x6996 >> nx) & 1; | |
6a08d0ab | 832 | } |
833 | #endif | |
9ce1b52b | 834 | |
835 | #ifdef L_udivmoddi4 | |
62c63f32 | 836 | |
a47053cf | 837 | #if (defined (L_udivdi3) || defined (L_divdi3) || \ |
838 | defined (L_umoddi3) || defined (L_moddi3)) | |
9dae5ac3 | 839 | static inline __attribute__ ((__always_inline__)) |
a47053cf | 840 | #endif |
cf378360 | 841 | UDWtype |
842 | __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) | |
62c63f32 | 843 | { |
ec7f942b | 844 | const DWunion nn = {.ll = n}; |
845 | const DWunion dd = {.ll = d}; | |
cf378360 | 846 | DWunion rr; |
847 | UWtype d0, d1, n0, n1, n2; | |
848 | UWtype q0, q1; | |
849 | UWtype b, bm; | |
62c63f32 | 850 | |
62c63f32 | 851 | d0 = dd.s.low; |
852 | d1 = dd.s.high; | |
853 | n0 = nn.s.low; | |
854 | n1 = nn.s.high; | |
855 | ||
856 | #if !UDIV_NEEDS_NORMALIZATION | |
857 | if (d1 == 0) | |
858 | { | |
859 | if (d0 > n1) | |
860 | { | |
861 | /* 0q = nn / 0D */ | |
862 | ||
863 | udiv_qrnnd (q0, n0, n1, n0, d0); | |
864 | q1 = 0; | |
865 | ||
866 | /* Remainder in n0. */ | |
867 | } | |
868 | else | |
869 | { | |
870 | /* qq = NN / 0d */ | |
871 | ||
872 | if (d0 == 0) | |
873 | d0 = 1 / d0; /* Divide intentionally by zero. */ | |
874 | ||
875 | udiv_qrnnd (q1, n1, 0, n1, d0); | |
876 | udiv_qrnnd (q0, n0, n1, n0, d0); | |
877 | ||
878 | /* Remainder in n0. */ | |
879 | } | |
880 | ||
881 | if (rp != 0) | |
882 | { | |
883 | rr.s.low = n0; | |
884 | rr.s.high = 0; | |
885 | *rp = rr.ll; | |
886 | } | |
887 | } | |
888 | ||
889 | #else /* UDIV_NEEDS_NORMALIZATION */ | |
890 | ||
891 | if (d1 == 0) | |
892 | { | |
893 | if (d0 > n1) | |
894 | { | |
895 | /* 0q = nn / 0D */ | |
896 | ||
897 | count_leading_zeros (bm, d0); | |
898 | ||
899 | if (bm != 0) | |
900 | { | |
901 | /* Normalize, i.e. make the most significant bit of the | |
902 | denominator set. */ | |
903 | ||
904 | d0 = d0 << bm; | |
cf378360 | 905 | n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); |
62c63f32 | 906 | n0 = n0 << bm; |
907 | } | |
908 | ||
909 | udiv_qrnnd (q0, n0, n1, n0, d0); | |
910 | q1 = 0; | |
911 | ||
912 | /* Remainder in n0 >> bm. */ | |
913 | } | |
914 | else | |
915 | { | |
916 | /* qq = NN / 0d */ | |
917 | ||
918 | if (d0 == 0) | |
919 | d0 = 1 / d0; /* Divide intentionally by zero. */ | |
920 | ||
921 | count_leading_zeros (bm, d0); | |
922 | ||
923 | if (bm == 0) | |
924 | { | |
925 | /* From (n1 >= d0) /\ (the most significant bit of d0 is set), | |
926 | conclude (the most significant bit of n1 is set) /\ (the | |
927 | leading quotient digit q1 = 1). | |
928 | ||
929 | This special case is necessary, not an optimization. | |
cf378360 | 930 | (Shifts counts of W_TYPE_SIZE are undefined.) */ |
62c63f32 | 931 | |
932 | n1 -= d0; | |
933 | q1 = 1; | |
934 | } | |
935 | else | |
936 | { | |
937 | /* Normalize. */ | |
938 | ||
cf378360 | 939 | b = W_TYPE_SIZE - bm; |
62c63f32 | 940 | |
941 | d0 = d0 << bm; | |
942 | n2 = n1 >> b; | |
943 | n1 = (n1 << bm) | (n0 >> b); | |
944 | n0 = n0 << bm; | |
945 | ||
946 | udiv_qrnnd (q1, n1, n2, n1, d0); | |
947 | } | |
948 | ||
a92771b8 | 949 | /* n1 != d0... */ |
62c63f32 | 950 | |
951 | udiv_qrnnd (q0, n0, n1, n0, d0); | |
952 | ||
953 | /* Remainder in n0 >> bm. */ | |
954 | } | |
955 | ||
956 | if (rp != 0) | |
957 | { | |
958 | rr.s.low = n0 >> bm; | |
959 | rr.s.high = 0; | |
960 | *rp = rr.ll; | |
961 | } | |
962 | } | |
963 | #endif /* UDIV_NEEDS_NORMALIZATION */ | |
964 | ||
965 | else | |
966 | { | |
967 | if (d1 > n1) | |
968 | { | |
969 | /* 00 = nn / DD */ | |
970 | ||
971 | q0 = 0; | |
972 | q1 = 0; | |
973 | ||
974 | /* Remainder in n1n0. */ | |
975 | if (rp != 0) | |
976 | { | |
977 | rr.s.low = n0; | |
978 | rr.s.high = n1; | |
979 | *rp = rr.ll; | |
980 | } | |
981 | } | |
982 | else | |
983 | { | |
984 | /* 0q = NN / dd */ | |
985 | ||
986 | count_leading_zeros (bm, d1); | |
987 | if (bm == 0) | |
988 | { | |
989 | /* From (n1 >= d1) /\ (the most significant bit of d1 is set), | |
990 | conclude (the most significant bit of n1 is set) /\ (the | |
991 | quotient digit q0 = 0 or 1). | |
992 | ||
993 | This special case is necessary, not an optimization. */ | |
994 | ||
995 | /* The condition on the next line takes advantage of that | |
996 | n1 >= d1 (true due to program flow). */ | |
997 | if (n1 > d1 || n0 >= d0) | |
998 | { | |
999 | q0 = 1; | |
1000 | sub_ddmmss (n1, n0, n1, n0, d1, d0); | |
1001 | } | |
1002 | else | |
1003 | q0 = 0; | |
1004 | ||
1005 | q1 = 0; | |
1006 | ||
1007 | if (rp != 0) | |
1008 | { | |
1009 | rr.s.low = n0; | |
1010 | rr.s.high = n1; | |
1011 | *rp = rr.ll; | |
1012 | } | |
1013 | } | |
1014 | else | |
1015 | { | |
cf378360 | 1016 | UWtype m1, m0; |
62c63f32 | 1017 | /* Normalize. */ |
1018 | ||
cf378360 | 1019 | b = W_TYPE_SIZE - bm; |
62c63f32 | 1020 | |
1021 | d1 = (d1 << bm) | (d0 >> b); | |
1022 | d0 = d0 << bm; | |
1023 | n2 = n1 >> b; | |
1024 | n1 = (n1 << bm) | (n0 >> b); | |
1025 | n0 = n0 << bm; | |
1026 | ||
1027 | udiv_qrnnd (q0, n1, n2, n1, d1); | |
1028 | umul_ppmm (m1, m0, q0, d0); | |
1029 | ||
1030 | if (m1 > n1 || (m1 == n1 && m0 > n0)) | |
1031 | { | |
1032 | q0--; | |
1033 | sub_ddmmss (m1, m0, m1, m0, d1, d0); | |
1034 | } | |
1035 | ||
1036 | q1 = 0; | |
1037 | ||
1038 | /* Remainder in (n1n0 - m1m0) >> bm. */ | |
1039 | if (rp != 0) | |
1040 | { | |
1041 | sub_ddmmss (n1, n0, n1, n0, m1, m0); | |
1042 | rr.s.low = (n1 << b) | (n0 >> bm); | |
1043 | rr.s.high = n1 >> bm; | |
1044 | *rp = rr.ll; | |
1045 | } | |
1046 | } | |
1047 | } | |
1048 | } | |
1049 | ||
ec7f942b | 1050 | const DWunion ww = {{.low = q0, .high = q1}}; |
62c63f32 | 1051 | return ww.ll; |
1052 | } | |
1053 | #endif | |
1054 | ||
1055 | #ifdef L_divdi3 | |
cf378360 | 1056 | DWtype |
1057 | __divdi3 (DWtype u, DWtype v) | |
62c63f32 | 1058 | { |
60a744a6 | 1059 | word_type c = 0; |
ec7f942b | 1060 | DWunion uu = {.ll = u}; |
1061 | DWunion vv = {.ll = v}; | |
cf378360 | 1062 | DWtype w; |
62c63f32 | 1063 | |
62c63f32 | 1064 | if (uu.s.high < 0) |
1065 | c = ~c, | |
f4dbfb4e | 1066 | uu.ll = -uu.ll; |
62c63f32 | 1067 | if (vv.s.high < 0) |
1068 | c = ~c, | |
f4dbfb4e | 1069 | vv.ll = -vv.ll; |
62c63f32 | 1070 | |
cf378360 | 1071 | w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); |
62c63f32 | 1072 | if (c) |
f4dbfb4e | 1073 | w = -w; |
62c63f32 | 1074 | |
1075 | return w; | |
1076 | } | |
1077 | #endif | |
1078 | ||
1079 | #ifdef L_moddi3 | |
cf378360 | 1080 | DWtype |
1081 | __moddi3 (DWtype u, DWtype v) | |
62c63f32 | 1082 | { |
60a744a6 | 1083 | word_type c = 0; |
ec7f942b | 1084 | DWunion uu = {.ll = u}; |
1085 | DWunion vv = {.ll = v}; | |
cf378360 | 1086 | DWtype w; |
62c63f32 | 1087 | |
62c63f32 | 1088 | if (uu.s.high < 0) |
1089 | c = ~c, | |
f4dbfb4e | 1090 | uu.ll = -uu.ll; |
62c63f32 | 1091 | if (vv.s.high < 0) |
f4dbfb4e | 1092 | vv.ll = -vv.ll; |
62c63f32 | 1093 | |
79cc8081 | 1094 | (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); |
62c63f32 | 1095 | if (c) |
f4dbfb4e | 1096 | w = -w; |
62c63f32 | 1097 | |
1098 | return w; | |
1099 | } | |
1100 | #endif | |
1101 | ||
1102 | #ifdef L_umoddi3 | |
cf378360 | 1103 | UDWtype |
1104 | __umoddi3 (UDWtype u, UDWtype v) | |
62c63f32 | 1105 | { |
cf378360 | 1106 | UDWtype w; |
62c63f32 | 1107 | |
1108 | (void) __udivmoddi4 (u, v, &w); | |
1109 | ||
1110 | return w; | |
1111 | } | |
1112 | #endif | |
1113 | ||
1114 | #ifdef L_udivdi3 | |
cf378360 | 1115 | UDWtype |
1116 | __udivdi3 (UDWtype n, UDWtype d) | |
62c63f32 | 1117 | { |
cf378360 | 1118 | return __udivmoddi4 (n, d, (UDWtype *) 0); |
62c63f32 | 1119 | } |
1120 | #endif | |
1121 | \f | |
1122 | #ifdef L_cmpdi2 | |
61d95568 | 1123 | word_type |
cf378360 | 1124 | __cmpdi2 (DWtype a, DWtype b) |
62c63f32 | 1125 | { |
ec7f942b | 1126 | const DWunion au = {.ll = a}; |
1127 | const DWunion bu = {.ll = b}; | |
62c63f32 | 1128 | |
1129 | if (au.s.high < bu.s.high) | |
1130 | return 0; | |
1131 | else if (au.s.high > bu.s.high) | |
1132 | return 2; | |
cf378360 | 1133 | if ((UWtype) au.s.low < (UWtype) bu.s.low) |
62c63f32 | 1134 | return 0; |
cf378360 | 1135 | else if ((UWtype) au.s.low > (UWtype) bu.s.low) |
62c63f32 | 1136 | return 2; |
1137 | return 1; | |
1138 | } | |
1139 | #endif | |
1140 | ||
1141 | #ifdef L_ucmpdi2 | |
61d95568 | 1142 | word_type |
cf378360 | 1143 | __ucmpdi2 (DWtype a, DWtype b) |
62c63f32 | 1144 | { |
ec7f942b | 1145 | const DWunion au = {.ll = a}; |
1146 | const DWunion bu = {.ll = b}; | |
62c63f32 | 1147 | |
cf378360 | 1148 | if ((UWtype) au.s.high < (UWtype) bu.s.high) |
62c63f32 | 1149 | return 0; |
cf378360 | 1150 | else if ((UWtype) au.s.high > (UWtype) bu.s.high) |
62c63f32 | 1151 | return 2; |
cf378360 | 1152 | if ((UWtype) au.s.low < (UWtype) bu.s.low) |
62c63f32 | 1153 | return 0; |
cf378360 | 1154 | else if ((UWtype) au.s.low > (UWtype) bu.s.low) |
62c63f32 | 1155 | return 2; |
1156 | return 1; | |
1157 | } | |
1158 | #endif | |
1159 | \f | |
dd84cabc | 1160 | #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) |
cf378360 | 1161 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1162 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
ade0e71b | 1163 | |
cf378360 | 1164 | DWtype |
d1138980 | 1165 | __fixunstfDI (TFtype a) |
ade0e71b | 1166 | { |
ade0e71b | 1167 | if (a < 0) |
1168 | return 0; | |
1169 | ||
1170 | /* Compute high word of result, as a flonum. */ | |
ec7f942b | 1171 | const TFtype b = (a / HIGH_WORD_COEFF); |
cf378360 | 1172 | /* Convert that to fixed (but not to DWtype!), |
ade0e71b | 1173 | and shift it into the high word. */ |
ec7f942b | 1174 | UDWtype v = (UWtype) b; |
ade0e71b | 1175 | v <<= WORD_SIZE; |
1176 | /* Remove high part from the TFtype, leaving the low part as flonum. */ | |
1177 | a -= (TFtype)v; | |
cf378360 | 1178 | /* Convert that to fixed (but not to DWtype!) and add it in. |
ade0e71b | 1179 | Sometimes A comes out negative. This is significant, since |
1180 | A has more bits than a long int does. */ | |
1181 | if (a < 0) | |
cf378360 | 1182 | v -= (UWtype) (- a); |
ade0e71b | 1183 | else |
cf378360 | 1184 | v += (UWtype) a; |
ade0e71b | 1185 | return v; |
1186 | } | |
1187 | #endif | |
1188 | ||
dd84cabc | 1189 | #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) |
cf378360 | 1190 | DWtype |
4f195a89 | 1191 | __fixtfdi (TFtype a) |
ade0e71b | 1192 | { |
1193 | if (a < 0) | |
d1138980 | 1194 | return - __fixunstfDI (-a); |
1195 | return __fixunstfDI (a); | |
ade0e71b | 1196 | } |
1197 | #endif | |
1198 | ||
77d98cfe | 1199 | #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) |
cf378360 | 1200 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1201 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
0e1cc047 | 1202 | |
cf378360 | 1203 | DWtype |
d1138980 | 1204 | __fixunsxfDI (XFtype a) |
0e1cc047 | 1205 | { |
0e1cc047 | 1206 | if (a < 0) |
1207 | return 0; | |
1208 | ||
1209 | /* Compute high word of result, as a flonum. */ | |
ec7f942b | 1210 | const XFtype b = (a / HIGH_WORD_COEFF); |
cf378360 | 1211 | /* Convert that to fixed (but not to DWtype!), |
0e1cc047 | 1212 | and shift it into the high word. */ |
ec7f942b | 1213 | UDWtype v = (UWtype) b; |
0e1cc047 | 1214 | v <<= WORD_SIZE; |
1215 | /* Remove high part from the XFtype, leaving the low part as flonum. */ | |
1216 | a -= (XFtype)v; | |
cf378360 | 1217 | /* Convert that to fixed (but not to DWtype!) and add it in. |
0e1cc047 | 1218 | Sometimes A comes out negative. This is significant, since |
1219 | A has more bits than a long int does. */ | |
1220 | if (a < 0) | |
cf378360 | 1221 | v -= (UWtype) (- a); |
0e1cc047 | 1222 | else |
cf378360 | 1223 | v += (UWtype) a; |
0e1cc047 | 1224 | return v; |
1225 | } | |
1226 | #endif | |
1227 | ||
77d98cfe | 1228 | #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) |
cf378360 | 1229 | DWtype |
4f195a89 | 1230 | __fixxfdi (XFtype a) |
0e1cc047 | 1231 | { |
1232 | if (a < 0) | |
d1138980 | 1233 | return - __fixunsxfDI (-a); |
1234 | return __fixunsxfDI (a); | |
0e1cc047 | 1235 | } |
1236 | #endif | |
1237 | ||
62c63f32 | 1238 | #ifdef L_fixunsdfdi |
cf378360 | 1239 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1240 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
62c63f32 | 1241 | |
cf378360 | 1242 | DWtype |
d1138980 | 1243 | __fixunsdfDI (DFtype a) |
62c63f32 | 1244 | { |
805e22b2 | 1245 | /* Get high part of result. The division here will just moves the radix |
1246 | point and will not cause any rounding. Then the conversion to integral | |
1247 | type chops result as desired. */ | |
ec7f942b | 1248 | const UWtype hi = a / HIGH_WORD_COEFF; |
62c63f32 | 1249 | |
805e22b2 | 1250 | /* Get low part of result. Convert `hi' to floating type and scale it back, |
1251 | then subtract this from the number being converted. This leaves the low | |
1252 | part. Convert that to integral type. */ | |
ec7f942b | 1253 | const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); |
805e22b2 | 1254 | |
1255 | /* Assemble result from the two parts. */ | |
1256 | return ((UDWtype) hi << WORD_SIZE) | lo; | |
62c63f32 | 1257 | } |
1258 | #endif | |
1259 | ||
1260 | #ifdef L_fixdfdi | |
cf378360 | 1261 | DWtype |
4f195a89 | 1262 | __fixdfdi (DFtype a) |
62c63f32 | 1263 | { |
1264 | if (a < 0) | |
d1138980 | 1265 | return - __fixunsdfDI (-a); |
1266 | return __fixunsdfDI (a); | |
62c63f32 | 1267 | } |
1268 | #endif | |
1269 | ||
1270 | #ifdef L_fixunssfdi | |
cf378360 | 1271 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1272 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
62c63f32 | 1273 | |
cf378360 | 1274 | DWtype |
d1138980 | 1275 | __fixunssfDI (SFtype original_a) |
62c63f32 | 1276 | { |
ade0e71b | 1277 | /* Convert the SFtype to a DFtype, because that is surely not going |
62c63f32 | 1278 | to lose any bits. Some day someone else can write a faster version |
ade0e71b | 1279 | that avoids converting to DFtype, and verify it really works right. */ |
ec7f942b | 1280 | const DFtype a = original_a; |
62c63f32 | 1281 | |
805e22b2 | 1282 | /* Get high part of result. The division here will just moves the radix |
1283 | point and will not cause any rounding. Then the conversion to integral | |
1284 | type chops result as desired. */ | |
ec7f942b | 1285 | const UWtype hi = a / HIGH_WORD_COEFF; |
62c63f32 | 1286 | |
805e22b2 | 1287 | /* Get low part of result. Convert `hi' to floating type and scale it back, |
1288 | then subtract this from the number being converted. This leaves the low | |
1289 | part. Convert that to integral type. */ | |
ec7f942b | 1290 | const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); |
805e22b2 | 1291 | |
1292 | /* Assemble result from the two parts. */ | |
1293 | return ((UDWtype) hi << WORD_SIZE) | lo; | |
62c63f32 | 1294 | } |
1295 | #endif | |
1296 | ||
1297 | #ifdef L_fixsfdi | |
cf378360 | 1298 | DWtype |
ade0e71b | 1299 | __fixsfdi (SFtype a) |
62c63f32 | 1300 | { |
1301 | if (a < 0) | |
d1138980 | 1302 | return - __fixunssfDI (-a); |
1303 | return __fixunssfDI (a); | |
62c63f32 | 1304 | } |
1305 | #endif | |
1306 | ||
77d98cfe | 1307 | #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) |
cf378360 | 1308 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1309 | #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) | |
1310 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
0e1cc047 | 1311 | |
1312 | XFtype | |
cf378360 | 1313 | __floatdixf (DWtype u) |
0e1cc047 | 1314 | { |
ec7f942b | 1315 | XFtype d = (Wtype) (u >> WORD_SIZE); |
0e1cc047 | 1316 | d *= HIGH_HALFWORD_COEFF; |
1317 | d *= HIGH_HALFWORD_COEFF; | |
cf378360 | 1318 | d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); |
0e1cc047 | 1319 | |
997d68fe | 1320 | return d; |
0e1cc047 | 1321 | } |
1322 | #endif | |
1323 | ||
dd84cabc | 1324 | #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) |
cf378360 | 1325 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1326 | #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) | |
1327 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
ade0e71b | 1328 | |
1329 | TFtype | |
cf378360 | 1330 | __floatditf (DWtype u) |
ade0e71b | 1331 | { |
ec7f942b | 1332 | TFtype d = (Wtype) (u >> WORD_SIZE); |
ade0e71b | 1333 | d *= HIGH_HALFWORD_COEFF; |
1334 | d *= HIGH_HALFWORD_COEFF; | |
cf378360 | 1335 | d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); |
ade0e71b | 1336 | |
997d68fe | 1337 | return d; |
ade0e71b | 1338 | } |
1339 | #endif | |
1340 | ||
62c63f32 | 1341 | #ifdef L_floatdidf |
cf378360 | 1342 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1343 | #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) | |
1344 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
62c63f32 | 1345 | |
ade0e71b | 1346 | DFtype |
cf378360 | 1347 | __floatdidf (DWtype u) |
62c63f32 | 1348 | { |
ec7f942b | 1349 | DFtype d = (Wtype) (u >> WORD_SIZE); |
62c63f32 | 1350 | d *= HIGH_HALFWORD_COEFF; |
1351 | d *= HIGH_HALFWORD_COEFF; | |
cf378360 | 1352 | d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); |
62c63f32 | 1353 | |
997d68fe | 1354 | return d; |
62c63f32 | 1355 | } |
1356 | #endif | |
1357 | ||
1358 | #ifdef L_floatdisf | |
cf378360 | 1359 | #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) |
1360 | #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) | |
1361 | #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) | |
87e97de6 | 1362 | |
536f5fb1 | 1363 | #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT) |
badfe841 | 1364 | #define DF_SIZE DBL_MANT_DIG |
1365 | #define SF_SIZE FLT_MANT_DIG | |
62c63f32 | 1366 | |
ade0e71b | 1367 | SFtype |
cf378360 | 1368 | __floatdisf (DWtype u) |
62c63f32 | 1369 | { |
b37ebc51 | 1370 | /* Protect against double-rounding error. |
1371 | Represent any low-order bits, that might be truncated in DFmode, | |
1372 | by a bit that won't be lost. The bit can go in anywhere below the | |
1373 | rounding position of the SFmode. A fixed mask and bit position | |
1374 | handles all usual configurations. It doesn't handle the case | |
1375 | of 128-bit DImode, however. */ | |
1376 | if (DF_SIZE < DI_SIZE | |
1377 | && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) | |
1378 | { | |
d1138980 | 1379 | #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE)) |
cf378360 | 1380 | if (! (- ((DWtype) 1 << DF_SIZE) < u |
1381 | && u < ((DWtype) 1 << DF_SIZE))) | |
b37ebc51 | 1382 | { |
d1138980 | 1383 | if ((UDWtype) u & (REP_BIT - 1)) |
f9c9dcd7 | 1384 | { |
1385 | u &= ~ (REP_BIT - 1); | |
1386 | u |= REP_BIT; | |
1387 | } | |
b37ebc51 | 1388 | } |
1389 | } | |
ec7f942b | 1390 | /* Do the calculation in DFmode |
1391 | so that we don't lose any of the precision of the high word | |
1392 | while multiplying it. */ | |
1393 | DFtype f = (Wtype) (u >> WORD_SIZE); | |
62c63f32 | 1394 | f *= HIGH_HALFWORD_COEFF; |
1395 | f *= HIGH_HALFWORD_COEFF; | |
cf378360 | 1396 | f += (UWtype) (u & (HIGH_WORD_COEFF - 1)); |
62c63f32 | 1397 | |
997d68fe | 1398 | return (SFtype) f; |
62c63f32 | 1399 | } |
1400 | #endif | |
1401 | ||
77d98cfe | 1402 | #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80 |
3873e172 | 1403 | /* Reenable the normal types, in case limits.h needs them. */ |
1404 | #undef char | |
1405 | #undef short | |
1406 | #undef int | |
1407 | #undef long | |
1408 | #undef unsigned | |
1409 | #undef float | |
1410 | #undef double | |
35e6d592 | 1411 | #undef MIN |
1412 | #undef MAX | |
ab195728 | 1413 | #include <limits.h> |
0e1cc047 | 1414 | |
cf378360 | 1415 | UWtype |
d1138980 | 1416 | __fixunsxfSI (XFtype a) |
0e1cc047 | 1417 | { |
7429c938 | 1418 | if (a >= - (DFtype) Wtype_MIN) |
1419 | return (Wtype) (a + Wtype_MIN) - Wtype_MIN; | |
cf378360 | 1420 | return (Wtype) a; |
0e1cc047 | 1421 | } |
1422 | #endif | |
1423 | ||
62c63f32 | 1424 | #ifdef L_fixunsdfsi |
3873e172 | 1425 | /* Reenable the normal types, in case limits.h needs them. */ |
1426 | #undef char | |
1427 | #undef short | |
1428 | #undef int | |
1429 | #undef long | |
1430 | #undef unsigned | |
1431 | #undef float | |
1432 | #undef double | |
35e6d592 | 1433 | #undef MIN |
1434 | #undef MAX | |
ab195728 | 1435 | #include <limits.h> |
62c63f32 | 1436 | |
cf378360 | 1437 | UWtype |
d1138980 | 1438 | __fixunsdfSI (DFtype a) |
62c63f32 | 1439 | { |
7429c938 | 1440 | if (a >= - (DFtype) Wtype_MIN) |
1441 | return (Wtype) (a + Wtype_MIN) - Wtype_MIN; | |
cf378360 | 1442 | return (Wtype) a; |
62c63f32 | 1443 | } |
1444 | #endif | |
1445 | ||
1446 | #ifdef L_fixunssfsi | |
3873e172 | 1447 | /* Reenable the normal types, in case limits.h needs them. */ |
1448 | #undef char | |
1449 | #undef short | |
1450 | #undef int | |
1451 | #undef long | |
1452 | #undef unsigned | |
1453 | #undef float | |
1454 | #undef double | |
35e6d592 | 1455 | #undef MIN |
1456 | #undef MAX | |
ab195728 | 1457 | #include <limits.h> |
62c63f32 | 1458 | |
cf378360 | 1459 | UWtype |
d1138980 | 1460 | __fixunssfSI (SFtype a) |
62c63f32 | 1461 | { |
7429c938 | 1462 | if (a >= - (SFtype) Wtype_MIN) |
1463 | return (Wtype) (a + Wtype_MIN) - Wtype_MIN; | |
cf378360 | 1464 | return (Wtype) a; |
62c63f32 | 1465 | } |
757c219d | 1466 | #endif |
1467 | \f | |
1468 | /* Integer power helper used from __builtin_powi for non-constant | |
1469 | exponents. */ | |
1470 | ||
1471 | #if defined(L_powisf2) || defined(L_powidf2) \ | |
1472 | || (defined(L_powixf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) \ | |
1473 | || (defined(L_powitf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) | |
1474 | # if defined(L_powisf2) | |
1475 | # define TYPE SFtype | |
1476 | # define NAME __powisf2 | |
1477 | # elif defined(L_powidf2) | |
1478 | # define TYPE DFtype | |
1479 | # define NAME __powidf2 | |
1480 | # elif defined(L_powixf2) | |
1481 | # define TYPE XFtype | |
1482 | # define NAME __powixf2 | |
1483 | # elif defined(L_powitf2) | |
1484 | # define TYPE TFtype | |
1485 | # define NAME __powitf2 | |
1486 | # endif | |
1487 | ||
1488 | TYPE | |
1489 | NAME (TYPE x, Wtype m) | |
1490 | { | |
1491 | UWtype n = m < 0 ? -m : m; | |
1492 | TYPE y = n % 2 ? x : 1; | |
1493 | while (n >>= 1) | |
1494 | { | |
1495 | x = x * x; | |
1496 | if (n % 2) | |
1497 | y = y * x; | |
1498 | } | |
1499 | return m < 0 ? 1/y : y; | |
1500 | } | |
1501 | ||
62c63f32 | 1502 | #endif |
1503 | \f | |
ade0e71b | 1504 | /* From here on down, the routines use normal data types. */ |
1505 | ||
1506 | #define SItype bogus_type | |
1507 | #define USItype bogus_type | |
1508 | #define DItype bogus_type | |
1509 | #define UDItype bogus_type | |
1510 | #define SFtype bogus_type | |
1511 | #define DFtype bogus_type | |
cf378360 | 1512 | #undef Wtype |
1513 | #undef UWtype | |
1514 | #undef HWtype | |
1515 | #undef UHWtype | |
1516 | #undef DWtype | |
1517 | #undef UDWtype | |
ade0e71b | 1518 | |
1519 | #undef char | |
1520 | #undef short | |
1521 | #undef int | |
1522 | #undef long | |
1523 | #undef unsigned | |
1524 | #undef float | |
1525 | #undef double | |
e674bcb7 | 1526 | \f |
1527 | #ifdef L__gcc_bcmp | |
1528 | ||
1529 | /* Like bcmp except the sign is meaningful. | |
c3418f42 | 1530 | Result is negative if S1 is less than S2, |
e674bcb7 | 1531 | positive if S1 is greater, 0 if S1 and S2 are equal. */ |
1532 | ||
1533 | int | |
b1e341a2 | 1534 | __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) |
e674bcb7 | 1535 | { |
1536 | while (size > 0) | |
1537 | { | |
ec7f942b | 1538 | const unsigned char c1 = *s1++, c2 = *s2++; |
e674bcb7 | 1539 | if (c1 != c2) |
1540 | return c1 - c2; | |
1541 | size--; | |
1542 | } | |
1543 | return 0; | |
1544 | } | |
ade0e71b | 1545 | |
0bad1e66 | 1546 | #endif |
1547 | \f | |
1548 | /* __eprintf used to be used by GCC's private version of <assert.h>. | |
1549 | We no longer provide that header, but this routine remains in libgcc.a | |
1550 | for binary backward compatibility. Note that it is not included in | |
1551 | the shared version of libgcc. */ | |
1552 | #ifdef L_eprintf | |
1553 | #ifndef inhibit_libc | |
1554 | ||
1555 | #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ | |
1556 | #include <stdio.h> | |
1557 | ||
1558 | void | |
1559 | __eprintf (const char *string, const char *expression, | |
1560 | unsigned int line, const char *filename) | |
1561 | { | |
1562 | fprintf (stderr, string, expression, line, filename); | |
1563 | fflush (stderr); | |
1564 | abort (); | |
1565 | } | |
1566 | ||
1567 | #endif | |
62c63f32 | 1568 | #endif |
1569 | ||
62c63f32 | 1570 | \f |
62c63f32 | 1571 | #ifdef L_clear_cache |
1572 | /* Clear part of an instruction cache. */ | |
1573 | ||
62c63f32 | 1574 | void |
abbe5a3d | 1575 | __clear_cache (char *beg __attribute__((__unused__)), |
1576 | char *end __attribute__((__unused__))) | |
62c63f32 | 1577 | { |
87e97de6 | 1578 | #ifdef CLEAR_INSN_CACHE |
efa58f1a | 1579 | CLEAR_INSN_CACHE (beg, end); |
efa58f1a | 1580 | #endif /* CLEAR_INSN_CACHE */ |
62c63f32 | 1581 | } |
1582 | ||
1583 | #endif /* L_clear_cache */ | |
1584 | \f | |
5577e296 | 1585 | #ifdef L_enable_execute_stack |
1586 | /* Attempt to turn on execute permission for the stack. */ | |
1587 | ||
1588 | #ifdef ENABLE_EXECUTE_STACK | |
1589 | ENABLE_EXECUTE_STACK | |
1590 | #else | |
1591 | void | |
1592 | __enable_execute_stack (void *addr __attribute__((__unused__))) | |
1593 | {} | |
1594 | #endif /* ENABLE_EXECUTE_STACK */ | |
1595 | ||
1596 | #endif /* L_enable_execute_stack */ | |
1597 | \f | |
62c63f32 | 1598 | #ifdef L_trampoline |
1599 | ||
1600 | /* Jump to a trampoline, loading the static chain address. */ | |
1601 | ||
f1959ea2 | 1602 | #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) |
8e782fcd | 1603 | |
4281d316 | 1604 | int |
71218a21 | 1605 | getpagesize (void) |
e30b7e49 | 1606 | { |
1607 | #ifdef _ALPHA_ | |
1608 | return 8192; | |
1609 | #else | |
1610 | return 4096; | |
1611 | #endif | |
1612 | } | |
1613 | ||
1ec6144c | 1614 | #ifdef __i386__ |
bdf89453 | 1615 | extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); |
1616 | #endif | |
1617 | ||
38e911c3 | 1618 | int |
1619 | mprotect (char *addr, int len, int prot) | |
e30b7e49 | 1620 | { |
1621 | int np, op; | |
1622 | ||
38e911c3 | 1623 | if (prot == 7) |
1624 | np = 0x40; | |
1625 | else if (prot == 5) | |
1626 | np = 0x20; | |
1627 | else if (prot == 4) | |
1628 | np = 0x10; | |
1629 | else if (prot == 3) | |
1630 | np = 0x04; | |
1631 | else if (prot == 1) | |
1632 | np = 0x02; | |
1633 | else if (prot == 0) | |
1634 | np = 0x01; | |
e30b7e49 | 1635 | |
1636 | if (VirtualProtect (addr, len, np, &op)) | |
1637 | return 0; | |
1638 | else | |
1639 | return -1; | |
e30b7e49 | 1640 | } |
1641 | ||
f1959ea2 | 1642 | #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ |
e30b7e49 | 1643 | |
87e97de6 | 1644 | #ifdef TRANSFER_FROM_TRAMPOLINE |
1645 | TRANSFER_FROM_TRAMPOLINE | |
62c63f32 | 1646 | #endif |
62c63f32 | 1647 | #endif /* L_trampoline */ |
1648 | \f | |
e678484c | 1649 | #ifndef __CYGWIN__ |
62c63f32 | 1650 | #ifdef L__main |
1651 | ||
1652 | #include "gbl-ctors.h" | |
0c945479 | 1653 | /* Some systems use __main in a way incompatible with its use in gcc, in these |
1654 | cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to | |
1655 | give the same symbol without quotes for an alternative entry point. You | |
a92771b8 | 1656 | must define both, or neither. */ |
0c945479 | 1657 | #ifndef NAME__MAIN |
1658 | #define NAME__MAIN "__main" | |
1659 | #define SYMBOL__MAIN __main | |
1660 | #endif | |
62c63f32 | 1661 | |
8313a782 | 1662 | #ifdef INIT_SECTION_ASM_OP |
1663 | #undef HAS_INIT_SECTION | |
1664 | #define HAS_INIT_SECTION | |
1665 | #endif | |
1666 | ||
1667 | #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) | |
a6881cf3 | 1668 | |
1669 | /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this | |
1670 | code to run constructors. In that case, we need to handle EH here, too. */ | |
1671 | ||
eb86c6db | 1672 | #ifdef EH_FRAME_SECTION_NAME |
899c9389 | 1673 | #include "unwind-dw2-fde.h" |
a6881cf3 | 1674 | extern unsigned char __EH_FRAME_BEGIN__[]; |
1675 | #endif | |
1676 | ||
62c63f32 | 1677 | /* Run all the global destructors on exit from the program. */ |
1678 | ||
1679 | void | |
71218a21 | 1680 | __do_global_dtors (void) |
62c63f32 | 1681 | { |
3a158972 | 1682 | #ifdef DO_GLOBAL_DTORS_BODY |
1683 | DO_GLOBAL_DTORS_BODY; | |
1684 | #else | |
113f9ca7 | 1685 | static func_ptr *p = __DTOR_LIST__ + 1; |
1686 | while (*p) | |
1687 | { | |
1688 | p++; | |
1689 | (*(p-1)) (); | |
1690 | } | |
3a158972 | 1691 | #endif |
eb86c6db | 1692 | #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) |
3b1bfdbe | 1693 | { |
1694 | static int completed = 0; | |
1695 | if (! completed) | |
1696 | { | |
1697 | completed = 1; | |
1698 | __deregister_frame_info (__EH_FRAME_BEGIN__); | |
1699 | } | |
1700 | } | |
a6881cf3 | 1701 | #endif |
62c63f32 | 1702 | } |
b7c87ff2 | 1703 | #endif |
62c63f32 | 1704 | |
8313a782 | 1705 | #ifndef HAS_INIT_SECTION |
62c63f32 | 1706 | /* Run all the global constructors on entry to the program. */ |
1707 | ||
62c63f32 | 1708 | void |
71218a21 | 1709 | __do_global_ctors (void) |
62c63f32 | 1710 | { |
eb86c6db | 1711 | #ifdef EH_FRAME_SECTION_NAME |
a6881cf3 | 1712 | { |
1713 | static struct object object; | |
1714 | __register_frame_info (__EH_FRAME_BEGIN__, &object); | |
1715 | } | |
1716 | #endif | |
62c63f32 | 1717 | DO_GLOBAL_CTORS_BODY; |
bd84a596 | 1718 | atexit (__do_global_dtors); |
62c63f32 | 1719 | } |
8313a782 | 1720 | #endif /* no HAS_INIT_SECTION */ |
62c63f32 | 1721 | |
8313a782 | 1722 | #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) |
62c63f32 | 1723 | /* Subroutine called automatically by `main'. |
1724 | Compiling a global function named `main' | |
1725 | produces an automatic call to this function at the beginning. | |
1726 | ||
1727 | For many systems, this routine calls __do_global_ctors. | |
1728 | For systems which support a .init section we use the .init section | |
1729 | to run __do_global_ctors, so we need not do anything here. */ | |
1730 | ||
f2dc410e | 1731 | extern void SYMBOL__MAIN (void); |
62c63f32 | 1732 | void |
f2dc410e | 1733 | SYMBOL__MAIN (void) |
62c63f32 | 1734 | { |
1735 | /* Support recursive calls to `main': run initializers just once. */ | |
5233d224 | 1736 | static int initialized; |
62c63f32 | 1737 | if (! initialized) |
1738 | { | |
1739 | initialized = 1; | |
1740 | __do_global_ctors (); | |
1741 | } | |
1742 | } | |
8313a782 | 1743 | #endif /* no HAS_INIT_SECTION or INVOKE__main */ |
62c63f32 | 1744 | |
1745 | #endif /* L__main */ | |
e678484c | 1746 | #endif /* __CYGWIN__ */ |
62c63f32 | 1747 | \f |
a0f2694a | 1748 | #ifdef L_ctors |
62c63f32 | 1749 | |
1750 | #include "gbl-ctors.h" | |
1751 | ||
1752 | /* Provide default definitions for the lists of constructors and | |
98ae6ed6 | 1753 | destructors, so that we don't get linker errors. These symbols are |
1754 | intentionally bss symbols, so that gld and/or collect will provide | |
1755 | the right values. */ | |
62c63f32 | 1756 | |
1757 | /* We declare the lists here with two elements each, | |
98ae6ed6 | 1758 | so that they are valid empty lists if no other definition is loaded. |
1759 | ||
1760 | If we are using the old "set" extensions to have the gnu linker | |
1761 | collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ | |
1762 | must be in the bss/common section. | |
1763 | ||
1764 | Long term no port should use those extensions. But many still do. */ | |
b13ae905 | 1765 | #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) |
e535c327 | 1766 | #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) |
d069195c | 1767 | func_ptr __CTOR_LIST__[2] = {0, 0}; |
1768 | func_ptr __DTOR_LIST__[2] = {0, 0}; | |
98ae6ed6 | 1769 | #else |
1770 | func_ptr __CTOR_LIST__[2]; | |
1771 | func_ptr __DTOR_LIST__[2]; | |
1772 | #endif | |
b13ae905 | 1773 | #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ |
a0f2694a | 1774 | #endif /* L_ctors */ |
62c63f32 | 1775 |