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