190075Sobrien/* This is a software floating point library which can be used 290075Sobrien for targets without hardware floating point. 3169689Skan Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 4169689Skan 2004, 2005 Free Software Foundation, Inc. 518334Speter 6169689SkanThis file is part of GCC. 718334Speter 8169689SkanGCC is free software; you can redistribute it and/or modify it under 9169689Skanthe terms of the GNU General Public License as published by the Free 10169689SkanSoftware Foundation; either version 2, or (at your option) any later 11169689Skanversion. 12169689Skan 1318334SpeterIn addition to the permissions in the GNU General Public License, the 1418334SpeterFree Software Foundation gives you unlimited permission to link the 15169689Skancompiled version of this file into combinations with other programs, 16169689Skanand to distribute those combinations without any restriction coming 17169689Skanfrom the use of this file. (The General Public License restrictions 18169689Skando apply in other respects; for example, they cover modification of 19169689Skanthe file, and distribution when not linked into a combine 20169689Skanexecutable.) 2118334Speter 22169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 23169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 24169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25169689Skanfor more details. 2618334Speter 2718334SpeterYou should have received a copy of the GNU General Public License 28169689Skanalong with GCC; see the file COPYING. If not, write to the Free 29169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 30169689Skan02110-1301, USA. */ 3118334Speter 3218334Speter/* This implements IEEE 754 format arithmetic, but does not provide a 3318334Speter mechanism for setting the rounding mode, or for generating or handling 3418334Speter exceptions. 3518334Speter 3618334Speter The original code by Steve Chamberlain, hacked by Mark Eichin and Jim 3718334Speter Wilson, all of Cygnus Support. */ 3818334Speter 3918334Speter/* The intended way to use this file is to make two copies, add `#define FLOAT' 4018334Speter to one copy, then compile both copies and add them to libgcc.a. */ 4118334Speter 4290075Sobrien#include "tconfig.h" 43132718Skan#include "coretypes.h" 44132718Skan#include "tm.h" 45132718Skan#include "config/fp-bit.h" 4650397Sobrien 47117395Skan/* The following macros can be defined to change the behavior of this file: 4818334Speter FLOAT: Implement a `float', aka SFmode, fp library. If this is not 4918334Speter defined, then this file implements a `double', aka DFmode, fp library. 5018334Speter FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e. 5118334Speter don't include float->double conversion which requires the double library. 5218334Speter This is useful only for machines which can't support doubles, e.g. some 5318334Speter 8-bit processors. 5418334Speter CMPtype: Specify the type that floating point compares should return. 5518334Speter This defaults to SItype, aka int. 5618334Speter US_SOFTWARE_GOFAST: This makes all entry points use the same names as the 5790075Sobrien US Software goFast library. 5818334Speter _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding 5990075Sobrien two integers to the FLO_union_type. 6090075Sobrien NO_DENORMALS: Disable handling of denormals. 6118334Speter NO_NANS: Disable nan and infinity handling 6218334Speter SMALL_MACHINE: Useful when operations on QIs and HIs are faster 6318334Speter than on an SI */ 6418334Speter 6550397Sobrien/* We don't currently support extended floats (long doubles) on machines 6650397Sobrien without hardware to deal with them. 6750397Sobrien 6850397Sobrien These stubs are just to keep the linker from complaining about unresolved 6950397Sobrien references which can be pulled in from libio & libstdc++, even if the 7050397Sobrien user isn't using long doubles. However, they may generate an unresolved 7150397Sobrien external to abort if abort is not used by the function, and the stubs 7250397Sobrien are referenced from within libc, since libgcc goes before and after the 7350397Sobrien system library. */ 7450397Sobrien 75117395Skan#ifdef DECLARE_LIBRARY_RENAMES 76117395Skan DECLARE_LIBRARY_RENAMES 77117395Skan#endif 78117395Skan 7950397Sobrien#ifdef EXTENDED_FLOAT_STUBS 80117395Skanextern void abort (void); 81117395Skanvoid __extendsfxf2 (void) { abort(); } 82117395Skanvoid __extenddfxf2 (void) { abort(); } 83117395Skanvoid __truncxfdf2 (void) { abort(); } 84117395Skanvoid __truncxfsf2 (void) { abort(); } 85117395Skanvoid __fixxfsi (void) { abort(); } 86117395Skanvoid __floatsixf (void) { abort(); } 87117395Skanvoid __addxf3 (void) { abort(); } 88117395Skanvoid __subxf3 (void) { abort(); } 89117395Skanvoid __mulxf3 (void) { abort(); } 90117395Skanvoid __divxf3 (void) { abort(); } 91117395Skanvoid __negxf2 (void) { abort(); } 92117395Skanvoid __eqxf2 (void) { abort(); } 93117395Skanvoid __nexf2 (void) { abort(); } 94117395Skanvoid __gtxf2 (void) { abort(); } 95117395Skanvoid __gexf2 (void) { abort(); } 96117395Skanvoid __lexf2 (void) { abort(); } 97117395Skanvoid __ltxf2 (void) { abort(); } 9850397Sobrien 99117395Skanvoid __extendsftf2 (void) { abort(); } 100117395Skanvoid __extenddftf2 (void) { abort(); } 101117395Skanvoid __trunctfdf2 (void) { abort(); } 102117395Skanvoid __trunctfsf2 (void) { abort(); } 103117395Skanvoid __fixtfsi (void) { abort(); } 104117395Skanvoid __floatsitf (void) { abort(); } 105117395Skanvoid __addtf3 (void) { abort(); } 106117395Skanvoid __subtf3 (void) { abort(); } 107117395Skanvoid __multf3 (void) { abort(); } 108117395Skanvoid __divtf3 (void) { abort(); } 109117395Skanvoid __negtf2 (void) { abort(); } 110117395Skanvoid __eqtf2 (void) { abort(); } 111117395Skanvoid __netf2 (void) { abort(); } 112117395Skanvoid __gttf2 (void) { abort(); } 113117395Skanvoid __getf2 (void) { abort(); } 114117395Skanvoid __letf2 (void) { abort(); } 115117395Skanvoid __lttf2 (void) { abort(); } 11650397Sobrien#else /* !EXTENDED_FLOAT_STUBS, rest of file */ 11750397Sobrien 11818334Speter/* IEEE "special" number predicates */ 11918334Speter 12018334Speter#ifdef NO_NANS 12118334Speter 12218334Speter#define nan() 0 12318334Speter#define isnan(x) 0 12418334Speter#define isinf(x) 0 12518334Speter#else 12618334Speter 12790075Sobrien#if defined L_thenan_sf 12890075Sobrienconst fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; 12990075Sobrien#elif defined L_thenan_df 13090075Sobrienconst fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} }; 131117395Skan#elif defined L_thenan_tf 132117395Skanconst fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} }; 133117395Skan#elif defined TFLOAT 134117395Skanextern const fp_number_type __thenan_tf; 13590075Sobrien#elif defined FLOAT 13690075Sobrienextern const fp_number_type __thenan_sf; 13790075Sobrien#else 13890075Sobrienextern const fp_number_type __thenan_df; 13990075Sobrien#endif 14090075Sobrien 14118334SpeterINLINE 14218334Speterstatic fp_number_type * 14390075Sobriennan (void) 14418334Speter{ 145117395Skan /* Discard the const qualifier... */ 146117395Skan#ifdef TFLOAT 147117395Skan return (fp_number_type *) (& __thenan_tf); 148117395Skan#elif defined FLOAT 14990075Sobrien return (fp_number_type *) (& __thenan_sf); 15090075Sobrien#else 15190075Sobrien return (fp_number_type *) (& __thenan_df); 15290075Sobrien#endif 15318334Speter} 15418334Speter 15518334SpeterINLINE 15618334Speterstatic int 15718334Speterisnan ( fp_number_type * x) 15818334Speter{ 159169689Skan return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN, 160169689Skan 0); 16118334Speter} 16218334Speter 16318334SpeterINLINE 16418334Speterstatic int 16518334Speterisinf ( fp_number_type * x) 16618334Speter{ 167169689Skan return __builtin_expect (x->class == CLASS_INFINITY, 0); 16818334Speter} 16918334Speter 17090075Sobrien#endif /* NO_NANS */ 17118334Speter 17218334SpeterINLINE 17318334Speterstatic int 17418334Speteriszero ( fp_number_type * x) 17518334Speter{ 17618334Speter return x->class == CLASS_ZERO; 17718334Speter} 17818334Speter 17918334SpeterINLINE 18018334Speterstatic void 18118334Speterflip_sign ( fp_number_type * x) 18218334Speter{ 18318334Speter x->sign = !x->sign; 18418334Speter} 18518334Speter 186169689Skan/* Count leading zeroes in N. */ 187169689SkanINLINE 188169689Skanstatic int 189169689Skanclzusi (USItype n) 190169689Skan{ 191169689Skan extern int __clzsi2 (USItype); 192169689Skan if (sizeof (USItype) == sizeof (unsigned int)) 193169689Skan return __builtin_clz (n); 194169689Skan else if (sizeof (USItype) == sizeof (unsigned long)) 195169689Skan return __builtin_clzl (n); 196169689Skan else if (sizeof (USItype) == sizeof (unsigned long long)) 197169689Skan return __builtin_clzll (n); 198169689Skan else 199169689Skan return __clzsi2 (n); 200169689Skan} 201169689Skan 20250397Sobrienextern FLO_type pack_d ( fp_number_type * ); 20350397Sobrien 204117395Skan#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) 20550397SobrienFLO_type 20618334Speterpack_d ( fp_number_type * src) 20718334Speter{ 20818334Speter FLO_union_type dst; 20918334Speter fractype fraction = src->fraction.ll; /* wasn't unsigned before? */ 21018334Speter int sign = src->sign; 21118334Speter int exp = 0; 21218334Speter 213117395Skan if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src))) 21418334Speter { 215117395Skan /* We can't represent these values accurately. By using the 216117395Skan largest possible magnitude, we guarantee that the conversion 217117395Skan of infinity is at least as big as any finite number. */ 21818334Speter exp = EXPMAX; 219117395Skan fraction = ((fractype) 1 << FRACBITS) - 1; 220117395Skan } 221117395Skan else if (isnan (src)) 222117395Skan { 223117395Skan exp = EXPMAX; 22418334Speter if (src->class == CLASS_QNAN || 1) 22518334Speter { 226132718Skan#ifdef QUIET_NAN_NEGATED 227132718Skan fraction |= QUIET_NAN - 1; 228132718Skan#else 22918334Speter fraction |= QUIET_NAN; 230132718Skan#endif 23118334Speter } 23218334Speter } 23318334Speter else if (isinf (src)) 23418334Speter { 23518334Speter exp = EXPMAX; 23618334Speter fraction = 0; 23718334Speter } 23818334Speter else if (iszero (src)) 23918334Speter { 24018334Speter exp = 0; 24118334Speter fraction = 0; 24218334Speter } 24318334Speter else if (fraction == 0) 24418334Speter { 24518334Speter exp = 0; 24618334Speter } 24718334Speter else 24818334Speter { 249169689Skan if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0)) 25018334Speter { 251117395Skan#ifdef NO_DENORMALS 252117395Skan /* Go straight to a zero representation if denormals are not 253117395Skan supported. The denormal handling would be harmless but 254117395Skan isn't unnecessary. */ 255117395Skan exp = 0; 256117395Skan fraction = 0; 257117395Skan#else /* NO_DENORMALS */ 25818334Speter /* This number's exponent is too low to fit into the bits 25918334Speter available in the number, so we'll store 0 in the exponent and 26018334Speter shift the fraction to the right to make up for it. */ 26118334Speter 26218334Speter int shift = NORMAL_EXPMIN - src->normal_exp; 26318334Speter 26418334Speter exp = 0; 26518334Speter 26618334Speter if (shift > FRAC_NBITS - NGARDS) 26718334Speter { 26818334Speter /* No point shifting, since it's more that 64 out. */ 26918334Speter fraction = 0; 27018334Speter } 27118334Speter else 27218334Speter { 27390075Sobrien int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0; 27490075Sobrien fraction = (fraction >> shift) | lowbit; 27518334Speter } 27690075Sobrien if ((fraction & GARDMASK) == GARDMSB) 27790075Sobrien { 27890075Sobrien if ((fraction & (1 << NGARDS))) 27990075Sobrien fraction += GARDROUND + 1; 28090075Sobrien } 28190075Sobrien else 28290075Sobrien { 28390075Sobrien /* Add to the guards to round up. */ 28490075Sobrien fraction += GARDROUND; 28590075Sobrien } 28690075Sobrien /* Perhaps the rounding means we now need to change the 28790075Sobrien exponent, because the fraction is no longer denormal. */ 28890075Sobrien if (fraction >= IMPLICIT_1) 28990075Sobrien { 29090075Sobrien exp += 1; 29190075Sobrien } 29218334Speter fraction >>= NGARDS; 293117395Skan#endif /* NO_DENORMALS */ 29418334Speter } 295117395Skan else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) 296169689Skan && __builtin_expect (src->normal_exp > EXPBIAS, 0)) 29718334Speter { 29818334Speter exp = EXPMAX; 29918334Speter fraction = 0; 30018334Speter } 30118334Speter else 30218334Speter { 30318334Speter exp = src->normal_exp + EXPBIAS; 304117395Skan if (!ROUND_TOWARDS_ZERO) 30518334Speter { 306117395Skan /* IF the gard bits are the all zero, but the first, then we're 307117395Skan half way between two numbers, choose the one which makes the 308117395Skan lsb of the answer 0. */ 309117395Skan if ((fraction & GARDMASK) == GARDMSB) 310117395Skan { 311117395Skan if (fraction & (1 << NGARDS)) 312117395Skan fraction += GARDROUND + 1; 313117395Skan } 314117395Skan else 315117395Skan { 316117395Skan /* Add a one to the guards to round up */ 317117395Skan fraction += GARDROUND; 318117395Skan } 319117395Skan if (fraction >= IMPLICIT_2) 320117395Skan { 321117395Skan fraction >>= 1; 322117395Skan exp += 1; 323117395Skan } 32418334Speter } 325117395Skan fraction >>= NGARDS; 326117395Skan 327117395Skan if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX) 32818334Speter { 329117395Skan /* Saturate on overflow. */ 330117395Skan exp = EXPMAX; 331117395Skan fraction = ((fractype) 1 << FRACBITS) - 1; 33218334Speter } 33318334Speter } 33418334Speter } 33518334Speter 33618334Speter /* We previously used bitfields to store the number, but this doesn't 33750397Sobrien handle little/big endian systems conveniently, so use shifts and 33818334Speter masks */ 33918334Speter#ifdef FLOAT_BIT_ORDER_MISMATCH 34018334Speter dst.bits.fraction = fraction; 34118334Speter dst.bits.exp = exp; 34218334Speter dst.bits.sign = sign; 34318334Speter#else 344117395Skan# if defined TFLOAT && defined HALFFRACBITS 345117395Skan { 346132718Skan halffractype high, low, unity; 347132718Skan int lowsign, lowexp; 348117395Skan 349132718Skan unity = (halffractype) 1 << HALFFRACBITS; 350117395Skan 351132718Skan /* Set HIGH to the high double's significand, masking out the implicit 1. 352132718Skan Set LOW to the low double's full significand. */ 353132718Skan high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1); 354132718Skan low = fraction & (unity * 2 - 1); 355117395Skan 356132718Skan /* Get the initial sign and exponent of the low double. */ 357132718Skan lowexp = exp - HALFFRACBITS - 1; 358132718Skan lowsign = sign; 359132718Skan 360132718Skan /* HIGH should be rounded like a normal double, making |LOW| <= 361132718Skan 0.5 ULP of HIGH. Assume round-to-nearest. */ 362132718Skan if (exp < EXPMAX) 363132718Skan if (low > unity || (low == unity && (high & 1) == 1)) 364132718Skan { 365132718Skan /* Round HIGH up and adjust LOW to match. */ 366132718Skan high++; 367132718Skan if (high == unity) 368132718Skan { 369132718Skan /* May make it infinite, but that's OK. */ 370132718Skan high = 0; 371132718Skan exp++; 372132718Skan } 373132718Skan low = unity * 2 - low; 374132718Skan lowsign ^= 1; 375132718Skan } 376132718Skan 377132718Skan high |= (halffractype) exp << HALFFRACBITS; 378132718Skan high |= (halffractype) sign << (HALFFRACBITS + EXPBITS); 379132718Skan 380117395Skan if (exp == EXPMAX || exp == 0 || low == 0) 381117395Skan low = 0; 382117395Skan else 383117395Skan { 384132718Skan while (lowexp > 0 && low < unity) 385117395Skan { 386117395Skan low <<= 1; 387132718Skan lowexp--; 388117395Skan } 389117395Skan 390132718Skan if (lowexp <= 0) 391117395Skan { 392117395Skan halffractype roundmsb, round; 393132718Skan int shift; 394117395Skan 395132718Skan shift = 1 - lowexp; 396132718Skan roundmsb = (1 << (shift - 1)); 397117395Skan round = low & ((roundmsb << 1) - 1); 398117395Skan 399132718Skan low >>= shift; 400132718Skan lowexp = 0; 401117395Skan 402132718Skan if (round > roundmsb || (round == roundmsb && (low & 1) == 1)) 403117395Skan { 404117395Skan low++; 405132718Skan if (low == unity) 406132718Skan /* LOW rounds up to the smallest normal number. */ 407132718Skan lowexp++; 408117395Skan } 409117395Skan } 410117395Skan 411132718Skan low &= unity - 1; 412132718Skan low |= (halffractype) lowexp << HALFFRACBITS; 413132718Skan low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS); 414117395Skan } 415132718Skan dst.value_raw = ((fractype) high << HALFSHIFT) | low; 416117395Skan } 417117395Skan# else 41818334Speter dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1); 41918334Speter dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS; 42018334Speter dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS); 421117395Skan# endif 42218334Speter#endif 42318334Speter 42418334Speter#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) 425117395Skan#ifdef TFLOAT 42618334Speter { 427117395Skan qrtrfractype tmp1 = dst.words[0]; 428117395Skan qrtrfractype tmp2 = dst.words[1]; 429117395Skan dst.words[0] = dst.words[3]; 430117395Skan dst.words[1] = dst.words[2]; 431117395Skan dst.words[2] = tmp2; 432117395Skan dst.words[3] = tmp1; 433117395Skan } 434117395Skan#else 435117395Skan { 43618334Speter halffractype tmp = dst.words[0]; 43718334Speter dst.words[0] = dst.words[1]; 43818334Speter dst.words[1] = tmp; 43918334Speter } 44018334Speter#endif 441117395Skan#endif 44218334Speter 44318334Speter return dst.value; 44418334Speter} 44550397Sobrien#endif 44618334Speter 447117395Skan#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf) 44850397Sobrienvoid 44918334Speterunpack_d (FLO_union_type * src, fp_number_type * dst) 45018334Speter{ 45118334Speter /* We previously used bitfields to store the number, but this doesn't 45250397Sobrien handle little/big endian systems conveniently, so use shifts and 45318334Speter masks */ 45418334Speter fractype fraction; 45518334Speter int exp; 45618334Speter int sign; 45718334Speter 45818334Speter#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT) 45918334Speter FLO_union_type swapped; 46018334Speter 461117395Skan#ifdef TFLOAT 462117395Skan swapped.words[0] = src->words[3]; 463117395Skan swapped.words[1] = src->words[2]; 464117395Skan swapped.words[2] = src->words[1]; 465117395Skan swapped.words[3] = src->words[0]; 466117395Skan#else 46718334Speter swapped.words[0] = src->words[1]; 46818334Speter swapped.words[1] = src->words[0]; 469117395Skan#endif 47018334Speter src = &swapped; 47118334Speter#endif 47218334Speter 47318334Speter#ifdef FLOAT_BIT_ORDER_MISMATCH 47418334Speter fraction = src->bits.fraction; 47518334Speter exp = src->bits.exp; 47618334Speter sign = src->bits.sign; 47718334Speter#else 478117395Skan# if defined TFLOAT && defined HALFFRACBITS 479117395Skan { 480117395Skan halffractype high, low; 481117395Skan 482117395Skan high = src->value_raw >> HALFSHIFT; 483117395Skan low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1); 484117395Skan 485117395Skan fraction = high & ((((fractype)1) << HALFFRACBITS) - 1); 486117395Skan fraction <<= FRACBITS - HALFFRACBITS; 487117395Skan exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); 488117395Skan sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1; 489117395Skan 490117395Skan if (exp != EXPMAX && exp != 0 && low != 0) 491117395Skan { 492117395Skan int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1); 493117395Skan int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1; 494117395Skan int shift; 495117395Skan fractype xlow; 496117395Skan 497117395Skan xlow = low & ((((fractype)1) << HALFFRACBITS) - 1); 498117395Skan if (lowexp) 499117395Skan xlow |= (((halffractype)1) << HALFFRACBITS); 500117395Skan else 501117395Skan lowexp = 1; 502117395Skan shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp); 503117395Skan if (shift > 0) 504117395Skan xlow <<= shift; 505117395Skan else if (shift < 0) 506117395Skan xlow >>= -shift; 507117395Skan if (sign == lowsign) 508117395Skan fraction += xlow; 509132718Skan else if (fraction >= xlow) 510132718Skan fraction -= xlow; 511117395Skan else 512132718Skan { 513132718Skan /* The high part is a power of two but the full number is lower. 514132718Skan This code will leave the implicit 1 in FRACTION, but we'd 515132718Skan have added that below anyway. */ 516132718Skan fraction = (((fractype) 1 << FRACBITS) - xlow) << 1; 517132718Skan exp--; 518132718Skan } 519117395Skan } 520117395Skan } 521117395Skan# else 522117395Skan fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1); 52318334Speter exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1); 52418334Speter sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1; 525117395Skan# endif 52618334Speter#endif 52718334Speter 52818334Speter dst->sign = sign; 52918334Speter if (exp == 0) 53018334Speter { 53118334Speter /* Hmm. Looks like 0 */ 53290075Sobrien if (fraction == 0 53390075Sobrien#ifdef NO_DENORMALS 53490075Sobrien || 1 53590075Sobrien#endif 53690075Sobrien ) 53718334Speter { 53818334Speter /* tastes like zero */ 53918334Speter dst->class = CLASS_ZERO; 54018334Speter } 54118334Speter else 54218334Speter { 543117395Skan /* Zero exponent with nonzero fraction - it's denormalized, 54418334Speter so there isn't a leading implicit one - we'll shift it so 54518334Speter it gets one. */ 54618334Speter dst->normal_exp = exp - EXPBIAS + 1; 54718334Speter fraction <<= NGARDS; 54818334Speter 54918334Speter dst->class = CLASS_NUMBER; 55018334Speter#if 1 55118334Speter while (fraction < IMPLICIT_1) 55218334Speter { 55318334Speter fraction <<= 1; 55418334Speter dst->normal_exp--; 55518334Speter } 55618334Speter#endif 55718334Speter dst->fraction.ll = fraction; 55818334Speter } 55918334Speter } 560169689Skan else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) 561169689Skan && __builtin_expect (exp == EXPMAX, 0)) 56218334Speter { 56318334Speter /* Huge exponent*/ 56418334Speter if (fraction == 0) 56518334Speter { 56618334Speter /* Attached to a zero fraction - means infinity */ 56718334Speter dst->class = CLASS_INFINITY; 56818334Speter } 56918334Speter else 57018334Speter { 571117395Skan /* Nonzero fraction, means nan */ 572132718Skan#ifdef QUIET_NAN_NEGATED 573132718Skan if ((fraction & QUIET_NAN) == 0) 574132718Skan#else 57550397Sobrien if (fraction & QUIET_NAN) 576132718Skan#endif 57718334Speter { 57850397Sobrien dst->class = CLASS_QNAN; 57918334Speter } 58018334Speter else 58118334Speter { 58250397Sobrien dst->class = CLASS_SNAN; 58318334Speter } 58418334Speter /* Keep the fraction part as the nan number */ 58518334Speter dst->fraction.ll = fraction; 58618334Speter } 58718334Speter } 58818334Speter else 58918334Speter { 59018334Speter /* Nothing strange about this number */ 59118334Speter dst->normal_exp = exp - EXPBIAS; 59218334Speter dst->class = CLASS_NUMBER; 59318334Speter dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1; 59418334Speter } 59518334Speter} 59690075Sobrien#endif /* L_unpack_df || L_unpack_sf */ 59718334Speter 598117395Skan#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) 59918334Speterstatic fp_number_type * 60018334Speter_fpadd_parts (fp_number_type * a, 60118334Speter fp_number_type * b, 60218334Speter fp_number_type * tmp) 60318334Speter{ 60418334Speter intfrac tfraction; 60518334Speter 60618334Speter /* Put commonly used fields in local variables. */ 60718334Speter int a_normal_exp; 60818334Speter int b_normal_exp; 60918334Speter fractype a_fraction; 61018334Speter fractype b_fraction; 61118334Speter 61218334Speter if (isnan (a)) 61318334Speter { 61418334Speter return a; 61518334Speter } 61618334Speter if (isnan (b)) 61718334Speter { 61818334Speter return b; 61918334Speter } 62018334Speter if (isinf (a)) 62118334Speter { 62218334Speter /* Adding infinities with opposite signs yields a NaN. */ 62318334Speter if (isinf (b) && a->sign != b->sign) 62418334Speter return nan (); 62518334Speter return a; 62618334Speter } 62718334Speter if (isinf (b)) 62818334Speter { 62918334Speter return b; 63018334Speter } 63118334Speter if (iszero (b)) 63218334Speter { 63350397Sobrien if (iszero (a)) 63450397Sobrien { 63550397Sobrien *tmp = *a; 63650397Sobrien tmp->sign = a->sign & b->sign; 63750397Sobrien return tmp; 63850397Sobrien } 63918334Speter return a; 64018334Speter } 64118334Speter if (iszero (a)) 64218334Speter { 64318334Speter return b; 64418334Speter } 64518334Speter 64618334Speter /* Got two numbers. shift the smaller and increment the exponent till 64718334Speter they're the same */ 64818334Speter { 64918334Speter int diff; 650169689Skan int sdiff; 65118334Speter 65218334Speter a_normal_exp = a->normal_exp; 65318334Speter b_normal_exp = b->normal_exp; 65418334Speter a_fraction = a->fraction.ll; 65518334Speter b_fraction = b->fraction.ll; 65618334Speter 65718334Speter diff = a_normal_exp - b_normal_exp; 658169689Skan sdiff = diff; 65918334Speter 66018334Speter if (diff < 0) 66118334Speter diff = -diff; 66218334Speter if (diff < FRAC_NBITS) 66318334Speter { 664169689Skan if (sdiff > 0) 66518334Speter { 666169689Skan b_normal_exp += diff; 667169689Skan LSHIFT (b_fraction, diff); 66818334Speter } 669169689Skan else if (sdiff < 0) 67018334Speter { 671169689Skan a_normal_exp += diff; 672169689Skan LSHIFT (a_fraction, diff); 67318334Speter } 67418334Speter } 67518334Speter else 67618334Speter { 67718334Speter /* Somethings's up.. choose the biggest */ 67818334Speter if (a_normal_exp > b_normal_exp) 67918334Speter { 68018334Speter b_normal_exp = a_normal_exp; 68118334Speter b_fraction = 0; 68218334Speter } 68318334Speter else 68418334Speter { 68518334Speter a_normal_exp = b_normal_exp; 68618334Speter a_fraction = 0; 68718334Speter } 68818334Speter } 68918334Speter } 69018334Speter 69118334Speter if (a->sign != b->sign) 69218334Speter { 69318334Speter if (a->sign) 69418334Speter { 69518334Speter tfraction = -a_fraction + b_fraction; 69618334Speter } 69718334Speter else 69818334Speter { 69918334Speter tfraction = a_fraction - b_fraction; 70018334Speter } 70152284Sobrien if (tfraction >= 0) 70218334Speter { 70318334Speter tmp->sign = 0; 70418334Speter tmp->normal_exp = a_normal_exp; 70518334Speter tmp->fraction.ll = tfraction; 70618334Speter } 70718334Speter else 70818334Speter { 70918334Speter tmp->sign = 1; 71018334Speter tmp->normal_exp = a_normal_exp; 71118334Speter tmp->fraction.ll = -tfraction; 71218334Speter } 71318334Speter /* and renormalize it */ 71418334Speter 71518334Speter while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll) 71618334Speter { 71718334Speter tmp->fraction.ll <<= 1; 71818334Speter tmp->normal_exp--; 71918334Speter } 72018334Speter } 72118334Speter else 72218334Speter { 72318334Speter tmp->sign = a->sign; 72418334Speter tmp->normal_exp = a_normal_exp; 72518334Speter tmp->fraction.ll = a_fraction + b_fraction; 72618334Speter } 72718334Speter tmp->class = CLASS_NUMBER; 72818334Speter /* Now the fraction is added, we have to shift down to renormalize the 72918334Speter number */ 73018334Speter 73118334Speter if (tmp->fraction.ll >= IMPLICIT_2) 73218334Speter { 733169689Skan LSHIFT (tmp->fraction.ll, 1); 73418334Speter tmp->normal_exp++; 73518334Speter } 73618334Speter return tmp; 73718334Speter 73818334Speter} 73918334Speter 74018334SpeterFLO_type 74118334Speteradd (FLO_type arg_a, FLO_type arg_b) 74218334Speter{ 74318334Speter fp_number_type a; 74418334Speter fp_number_type b; 74518334Speter fp_number_type tmp; 74618334Speter fp_number_type *res; 74790075Sobrien FLO_union_type au, bu; 74818334Speter 74990075Sobrien au.value = arg_a; 75090075Sobrien bu.value = arg_b; 75118334Speter 75290075Sobrien unpack_d (&au, &a); 75390075Sobrien unpack_d (&bu, &b); 75490075Sobrien 75518334Speter res = _fpadd_parts (&a, &b, &tmp); 75618334Speter 75718334Speter return pack_d (res); 75818334Speter} 75918334Speter 76018334SpeterFLO_type 76118334Spetersub (FLO_type arg_a, FLO_type arg_b) 76218334Speter{ 76318334Speter fp_number_type a; 76418334Speter fp_number_type b; 76518334Speter fp_number_type tmp; 76618334Speter fp_number_type *res; 76790075Sobrien FLO_union_type au, bu; 76818334Speter 76990075Sobrien au.value = arg_a; 77090075Sobrien bu.value = arg_b; 77118334Speter 77290075Sobrien unpack_d (&au, &a); 77390075Sobrien unpack_d (&bu, &b); 77490075Sobrien 77518334Speter b.sign ^= 1; 77618334Speter 77718334Speter res = _fpadd_parts (&a, &b, &tmp); 77818334Speter 77918334Speter return pack_d (res); 78018334Speter} 78190075Sobrien#endif /* L_addsub_sf || L_addsub_df */ 78218334Speter 783117395Skan#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) 784117395Skanstatic inline __attribute__ ((__always_inline__)) fp_number_type * 78518334Speter_fpmul_parts ( fp_number_type * a, 78618334Speter fp_number_type * b, 78718334Speter fp_number_type * tmp) 78818334Speter{ 78918334Speter fractype low = 0; 79018334Speter fractype high = 0; 79118334Speter 79218334Speter if (isnan (a)) 79318334Speter { 79418334Speter a->sign = a->sign != b->sign; 79518334Speter return a; 79618334Speter } 79718334Speter if (isnan (b)) 79818334Speter { 79918334Speter b->sign = a->sign != b->sign; 80018334Speter return b; 80118334Speter } 80218334Speter if (isinf (a)) 80318334Speter { 80418334Speter if (iszero (b)) 80518334Speter return nan (); 80618334Speter a->sign = a->sign != b->sign; 80718334Speter return a; 80818334Speter } 80918334Speter if (isinf (b)) 81018334Speter { 81118334Speter if (iszero (a)) 81218334Speter { 81318334Speter return nan (); 81418334Speter } 81518334Speter b->sign = a->sign != b->sign; 81618334Speter return b; 81718334Speter } 81818334Speter if (iszero (a)) 81918334Speter { 82018334Speter a->sign = a->sign != b->sign; 82118334Speter return a; 82218334Speter } 82318334Speter if (iszero (b)) 82418334Speter { 82518334Speter b->sign = a->sign != b->sign; 82618334Speter return b; 82718334Speter } 82818334Speter 82990075Sobrien /* Calculate the mantissa by multiplying both numbers to get a 83090075Sobrien twice-as-wide number. */ 83118334Speter { 832117395Skan#if defined(NO_DI_MODE) || defined(TFLOAT) 83318334Speter { 83450397Sobrien fractype x = a->fraction.ll; 83550397Sobrien fractype ylow = b->fraction.ll; 83650397Sobrien fractype yhigh = 0; 83750397Sobrien int bit; 83850397Sobrien 83918334Speter /* ??? This does multiplies one bit at a time. Optimize. */ 84018334Speter for (bit = 0; bit < FRAC_NBITS; bit++) 84118334Speter { 84218334Speter int carry; 84318334Speter 84418334Speter if (x & 1) 84518334Speter { 84618334Speter carry = (low += ylow) < ylow; 84718334Speter high += yhigh + carry; 84818334Speter } 84918334Speter yhigh <<= 1; 85018334Speter if (ylow & FRACHIGH) 85118334Speter { 85218334Speter yhigh |= 1; 85318334Speter } 85418334Speter ylow <<= 1; 85518334Speter x >>= 1; 85618334Speter } 85718334Speter } 85818334Speter#elif defined(FLOAT) 85990075Sobrien /* Multiplying two USIs to get a UDI, we're safe. */ 86018334Speter { 86190075Sobrien UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll; 86218334Speter 86390075Sobrien high = answer >> BITS_PER_SI; 86418334Speter low = answer; 86518334Speter } 86618334Speter#else 86790075Sobrien /* fractype is DImode, but we need the result to be twice as wide. 86890075Sobrien Assuming a widening multiply from DImode to TImode is not 86990075Sobrien available, build one by hand. */ 87018334Speter { 87190075Sobrien USItype nl = a->fraction.ll; 87290075Sobrien USItype nh = a->fraction.ll >> BITS_PER_SI; 87390075Sobrien USItype ml = b->fraction.ll; 87490075Sobrien USItype mh = b->fraction.ll >> BITS_PER_SI; 87590075Sobrien UDItype pp_ll = (UDItype) ml * nl; 87690075Sobrien UDItype pp_hl = (UDItype) mh * nl; 87790075Sobrien UDItype pp_lh = (UDItype) ml * nh; 87890075Sobrien UDItype pp_hh = (UDItype) mh * nh; 87918334Speter UDItype res2 = 0; 88018334Speter UDItype res0 = 0; 88118334Speter UDItype ps_hh__ = pp_hl + pp_lh; 88218334Speter if (ps_hh__ < pp_hl) 88390075Sobrien res2 += (UDItype)1 << BITS_PER_SI; 88490075Sobrien pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI; 88518334Speter res0 = pp_ll + pp_hl; 88618334Speter if (res0 < pp_ll) 88718334Speter res2++; 88890075Sobrien res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh; 88918334Speter high = res2; 89018334Speter low = res0; 89118334Speter } 89218334Speter#endif 89318334Speter } 89418334Speter 895117395Skan tmp->normal_exp = a->normal_exp + b->normal_exp 896117395Skan + FRAC_NBITS - (FRACBITS + NGARDS); 89718334Speter tmp->sign = a->sign != b->sign; 89818334Speter while (high >= IMPLICIT_2) 89918334Speter { 90018334Speter tmp->normal_exp++; 90118334Speter if (high & 1) 90218334Speter { 90318334Speter low >>= 1; 90418334Speter low |= FRACHIGH; 90518334Speter } 90618334Speter high >>= 1; 90718334Speter } 90818334Speter while (high < IMPLICIT_1) 90918334Speter { 91018334Speter tmp->normal_exp--; 91118334Speter 91218334Speter high <<= 1; 91318334Speter if (low & FRACHIGH) 91418334Speter high |= 1; 91518334Speter low <<= 1; 91618334Speter } 917169689Skan 918117395Skan if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB) 91918334Speter { 92018334Speter if (high & (1 << NGARDS)) 92118334Speter { 922169689Skan /* Because we're half way, we would round to even by adding 923169689Skan GARDROUND + 1, except that's also done in the packing 924169689Skan function, and rounding twice will lose precision and cause 925169689Skan the result to be too far off. Example: 32-bit floats with 926169689Skan bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp 927169689Skan off), not 0x1000 (more than 0.5ulp off). */ 92818334Speter } 92918334Speter else if (low) 93018334Speter { 931169689Skan /* We're a further than half way by a small amount corresponding 932169689Skan to the bits set in "low". Knowing that, we round here and 933169689Skan not in pack_d, because there we don't have "low" available 934169689Skan anymore. */ 93518334Speter high += GARDROUND + 1; 936169689Skan 937169689Skan /* Avoid further rounding in pack_d. */ 938169689Skan high &= ~(fractype) GARDMASK; 93918334Speter } 94018334Speter } 94118334Speter tmp->fraction.ll = high; 94218334Speter tmp->class = CLASS_NUMBER; 94318334Speter return tmp; 94418334Speter} 94518334Speter 94618334SpeterFLO_type 94718334Spetermultiply (FLO_type arg_a, FLO_type arg_b) 94818334Speter{ 94918334Speter fp_number_type a; 95018334Speter fp_number_type b; 95118334Speter fp_number_type tmp; 95218334Speter fp_number_type *res; 95390075Sobrien FLO_union_type au, bu; 95418334Speter 95590075Sobrien au.value = arg_a; 95690075Sobrien bu.value = arg_b; 95718334Speter 95890075Sobrien unpack_d (&au, &a); 95990075Sobrien unpack_d (&bu, &b); 96090075Sobrien 96118334Speter res = _fpmul_parts (&a, &b, &tmp); 96218334Speter 96318334Speter return pack_d (res); 96418334Speter} 965169689Skan#endif /* L_mul_sf || L_mul_df || L_mul_tf */ 96618334Speter 967117395Skan#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) 968117395Skanstatic inline __attribute__ ((__always_inline__)) fp_number_type * 96918334Speter_fpdiv_parts (fp_number_type * a, 97052284Sobrien fp_number_type * b) 97118334Speter{ 97250397Sobrien fractype bit; 97318334Speter fractype numerator; 97418334Speter fractype denominator; 97518334Speter fractype quotient; 97618334Speter 97718334Speter if (isnan (a)) 97818334Speter { 97918334Speter return a; 98018334Speter } 98118334Speter if (isnan (b)) 98218334Speter { 98318334Speter return b; 98418334Speter } 98550397Sobrien 98650397Sobrien a->sign = a->sign ^ b->sign; 98750397Sobrien 98818334Speter if (isinf (a) || iszero (a)) 98918334Speter { 99018334Speter if (a->class == b->class) 99118334Speter return nan (); 99218334Speter return a; 99318334Speter } 99418334Speter 99518334Speter if (isinf (b)) 99618334Speter { 99718334Speter a->fraction.ll = 0; 99818334Speter a->normal_exp = 0; 99918334Speter return a; 100018334Speter } 100118334Speter if (iszero (b)) 100218334Speter { 100318334Speter a->class = CLASS_INFINITY; 100450397Sobrien return a; 100518334Speter } 100618334Speter 100718334Speter /* Calculate the mantissa by multiplying both 64bit numbers to get a 100818334Speter 128 bit number */ 100918334Speter { 101018334Speter /* quotient = 101118334Speter ( numerator / denominator) * 2^(numerator exponent - denominator exponent) 101218334Speter */ 101318334Speter 101418334Speter a->normal_exp = a->normal_exp - b->normal_exp; 101518334Speter numerator = a->fraction.ll; 101618334Speter denominator = b->fraction.ll; 101718334Speter 101818334Speter if (numerator < denominator) 101918334Speter { 102018334Speter /* Fraction will be less than 1.0 */ 102118334Speter numerator *= 2; 102218334Speter a->normal_exp--; 102318334Speter } 102418334Speter bit = IMPLICIT_1; 102518334Speter quotient = 0; 102618334Speter /* ??? Does divide one bit at a time. Optimize. */ 102718334Speter while (bit) 102818334Speter { 102918334Speter if (numerator >= denominator) 103018334Speter { 103118334Speter quotient |= bit; 103218334Speter numerator -= denominator; 103318334Speter } 103418334Speter bit >>= 1; 103518334Speter numerator *= 2; 103618334Speter } 103718334Speter 1038117395Skan if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB) 103918334Speter { 104018334Speter if (quotient & (1 << NGARDS)) 104118334Speter { 1042169689Skan /* Because we're half way, we would round to even by adding 1043169689Skan GARDROUND + 1, except that's also done in the packing 1044169689Skan function, and rounding twice will lose precision and cause 1045169689Skan the result to be too far off. */ 104618334Speter } 104718334Speter else if (numerator) 104818334Speter { 1049169689Skan /* We're a further than half way by the small amount 1050169689Skan corresponding to the bits set in "numerator". Knowing 1051169689Skan that, we round here and not in pack_d, because there we 1052169689Skan don't have "numerator" available anymore. */ 105318334Speter quotient += GARDROUND + 1; 1054169689Skan 1055169689Skan /* Avoid further rounding in pack_d. */ 1056169689Skan quotient &= ~(fractype) GARDMASK; 105718334Speter } 105818334Speter } 105918334Speter 106018334Speter a->fraction.ll = quotient; 106118334Speter return (a); 106218334Speter } 106318334Speter} 106418334Speter 106518334SpeterFLO_type 106618334Speterdivide (FLO_type arg_a, FLO_type arg_b) 106718334Speter{ 106818334Speter fp_number_type a; 106918334Speter fp_number_type b; 107018334Speter fp_number_type *res; 107190075Sobrien FLO_union_type au, bu; 107218334Speter 107390075Sobrien au.value = arg_a; 107490075Sobrien bu.value = arg_b; 107518334Speter 107690075Sobrien unpack_d (&au, &a); 107790075Sobrien unpack_d (&bu, &b); 107890075Sobrien 107952284Sobrien res = _fpdiv_parts (&a, &b); 108018334Speter 108118334Speter return pack_d (res); 108218334Speter} 108390075Sobrien#endif /* L_div_sf || L_div_df */ 108418334Speter 1085117395Skan#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \ 1086117395Skan || defined(L_fpcmp_parts_tf) 108718334Speter/* according to the demo, fpcmp returns a comparison with 0... thus 108818334Speter a<b -> -1 108918334Speter a==b -> 0 109018334Speter a>b -> +1 109118334Speter */ 109218334Speter 109350397Sobrienint 109450397Sobrien__fpcmp_parts (fp_number_type * a, fp_number_type * b) 109518334Speter{ 109618334Speter#if 0 1097117395Skan /* either nan -> unordered. Must be checked outside of this routine. */ 109818334Speter if (isnan (a) && isnan (b)) 109918334Speter { 110018334Speter return 1; /* still unordered! */ 110118334Speter } 110218334Speter#endif 110318334Speter 110418334Speter if (isnan (a) || isnan (b)) 110518334Speter { 110618334Speter return 1; /* how to indicate unordered compare? */ 110718334Speter } 110818334Speter if (isinf (a) && isinf (b)) 110918334Speter { 111018334Speter /* +inf > -inf, but +inf != +inf */ 111118334Speter /* b \a| +inf(0)| -inf(1) 111218334Speter ______\+--------+-------- 111318334Speter +inf(0)| a==b(0)| a<b(-1) 111418334Speter -------+--------+-------- 111518334Speter -inf(1)| a>b(1) | a==b(0) 111618334Speter -------+--------+-------- 1117117395Skan So since unordered must be nonzero, just line up the columns... 111818334Speter */ 111918334Speter return b->sign - a->sign; 112018334Speter } 1121117395Skan /* but not both... */ 112218334Speter if (isinf (a)) 112318334Speter { 112418334Speter return a->sign ? -1 : 1; 112518334Speter } 112618334Speter if (isinf (b)) 112718334Speter { 112818334Speter return b->sign ? 1 : -1; 112918334Speter } 113018334Speter if (iszero (a) && iszero (b)) 113118334Speter { 113218334Speter return 0; 113318334Speter } 113418334Speter if (iszero (a)) 113518334Speter { 113618334Speter return b->sign ? 1 : -1; 113718334Speter } 113818334Speter if (iszero (b)) 113918334Speter { 114018334Speter return a->sign ? -1 : 1; 114118334Speter } 1142117395Skan /* now both are "normal". */ 114318334Speter if (a->sign != b->sign) 114418334Speter { 114518334Speter /* opposite signs */ 114618334Speter return a->sign ? -1 : 1; 114718334Speter } 114818334Speter /* same sign; exponents? */ 114918334Speter if (a->normal_exp > b->normal_exp) 115018334Speter { 115118334Speter return a->sign ? -1 : 1; 115218334Speter } 115318334Speter if (a->normal_exp < b->normal_exp) 115418334Speter { 115518334Speter return a->sign ? 1 : -1; 115618334Speter } 1157117395Skan /* same exponents; check size. */ 115818334Speter if (a->fraction.ll > b->fraction.ll) 115918334Speter { 116018334Speter return a->sign ? -1 : 1; 116118334Speter } 116218334Speter if (a->fraction.ll < b->fraction.ll) 116318334Speter { 116418334Speter return a->sign ? 1 : -1; 116518334Speter } 1166117395Skan /* after all that, they're equal. */ 116718334Speter return 0; 116818334Speter} 116950397Sobrien#endif 117018334Speter 1171117395Skan#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf) 117218334SpeterCMPtype 117318334Spetercompare (FLO_type arg_a, FLO_type arg_b) 117418334Speter{ 117518334Speter fp_number_type a; 117618334Speter fp_number_type b; 117790075Sobrien FLO_union_type au, bu; 117818334Speter 117990075Sobrien au.value = arg_a; 118090075Sobrien bu.value = arg_b; 118118334Speter 118290075Sobrien unpack_d (&au, &a); 118390075Sobrien unpack_d (&bu, &b); 118490075Sobrien 118550397Sobrien return __fpcmp_parts (&a, &b); 118618334Speter} 118790075Sobrien#endif /* L_compare_sf || L_compare_df */ 118818334Speter 118918334Speter#ifndef US_SOFTWARE_GOFAST 119018334Speter 119118334Speter/* These should be optimized for their specific tasks someday. */ 119218334Speter 1193117395Skan#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) 119418334SpeterCMPtype 119518334Speter_eq_f2 (FLO_type arg_a, FLO_type arg_b) 119618334Speter{ 119718334Speter fp_number_type a; 119818334Speter fp_number_type b; 119990075Sobrien FLO_union_type au, bu; 120018334Speter 120190075Sobrien au.value = arg_a; 120290075Sobrien bu.value = arg_b; 120318334Speter 120490075Sobrien unpack_d (&au, &a); 120590075Sobrien unpack_d (&bu, &b); 120690075Sobrien 120718334Speter if (isnan (&a) || isnan (&b)) 120818334Speter return 1; /* false, truth == 0 */ 120918334Speter 121050397Sobrien return __fpcmp_parts (&a, &b) ; 121118334Speter} 121290075Sobrien#endif /* L_eq_sf || L_eq_df */ 121318334Speter 1214117395Skan#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) 121518334SpeterCMPtype 121618334Speter_ne_f2 (FLO_type arg_a, FLO_type arg_b) 121718334Speter{ 121818334Speter fp_number_type a; 121918334Speter fp_number_type b; 122090075Sobrien FLO_union_type au, bu; 122118334Speter 122290075Sobrien au.value = arg_a; 122390075Sobrien bu.value = arg_b; 122418334Speter 122590075Sobrien unpack_d (&au, &a); 122690075Sobrien unpack_d (&bu, &b); 122790075Sobrien 122818334Speter if (isnan (&a) || isnan (&b)) 122918334Speter return 1; /* true, truth != 0 */ 123018334Speter 123150397Sobrien return __fpcmp_parts (&a, &b) ; 123218334Speter} 123390075Sobrien#endif /* L_ne_sf || L_ne_df */ 123418334Speter 1235117395Skan#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) 123618334SpeterCMPtype 123718334Speter_gt_f2 (FLO_type arg_a, FLO_type arg_b) 123818334Speter{ 123918334Speter fp_number_type a; 124018334Speter fp_number_type b; 124190075Sobrien FLO_union_type au, bu; 124218334Speter 124390075Sobrien au.value = arg_a; 124490075Sobrien bu.value = arg_b; 124518334Speter 124690075Sobrien unpack_d (&au, &a); 124790075Sobrien unpack_d (&bu, &b); 124890075Sobrien 124918334Speter if (isnan (&a) || isnan (&b)) 125018334Speter return -1; /* false, truth > 0 */ 125118334Speter 125250397Sobrien return __fpcmp_parts (&a, &b); 125318334Speter} 125490075Sobrien#endif /* L_gt_sf || L_gt_df */ 125518334Speter 1256117395Skan#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) 125718334SpeterCMPtype 125818334Speter_ge_f2 (FLO_type arg_a, FLO_type arg_b) 125918334Speter{ 126018334Speter fp_number_type a; 126118334Speter fp_number_type b; 126290075Sobrien FLO_union_type au, bu; 126318334Speter 126490075Sobrien au.value = arg_a; 126590075Sobrien bu.value = arg_b; 126618334Speter 126790075Sobrien unpack_d (&au, &a); 126890075Sobrien unpack_d (&bu, &b); 126990075Sobrien 127018334Speter if (isnan (&a) || isnan (&b)) 127118334Speter return -1; /* false, truth >= 0 */ 127250397Sobrien return __fpcmp_parts (&a, &b) ; 127318334Speter} 127490075Sobrien#endif /* L_ge_sf || L_ge_df */ 127518334Speter 1276117395Skan#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) 127718334SpeterCMPtype 127818334Speter_lt_f2 (FLO_type arg_a, FLO_type arg_b) 127918334Speter{ 128018334Speter fp_number_type a; 128118334Speter fp_number_type b; 128290075Sobrien FLO_union_type au, bu; 128318334Speter 128490075Sobrien au.value = arg_a; 128590075Sobrien bu.value = arg_b; 128618334Speter 128790075Sobrien unpack_d (&au, &a); 128890075Sobrien unpack_d (&bu, &b); 128990075Sobrien 129018334Speter if (isnan (&a) || isnan (&b)) 129118334Speter return 1; /* false, truth < 0 */ 129218334Speter 129350397Sobrien return __fpcmp_parts (&a, &b); 129418334Speter} 129590075Sobrien#endif /* L_lt_sf || L_lt_df */ 129618334Speter 1297117395Skan#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) 129818334SpeterCMPtype 129918334Speter_le_f2 (FLO_type arg_a, FLO_type arg_b) 130018334Speter{ 130118334Speter fp_number_type a; 130218334Speter fp_number_type b; 130390075Sobrien FLO_union_type au, bu; 130418334Speter 130590075Sobrien au.value = arg_a; 130690075Sobrien bu.value = arg_b; 130718334Speter 130890075Sobrien unpack_d (&au, &a); 130990075Sobrien unpack_d (&bu, &b); 131090075Sobrien 131118334Speter if (isnan (&a) || isnan (&b)) 131218334Speter return 1; /* false, truth <= 0 */ 131318334Speter 131450397Sobrien return __fpcmp_parts (&a, &b) ; 131518334Speter} 131690075Sobrien#endif /* L_le_sf || L_le_df */ 131718334Speter 1318117395Skan#endif /* ! US_SOFTWARE_GOFAST */ 1319117395Skan 1320117395Skan#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) 132190075SobrienCMPtype 132290075Sobrien_unord_f2 (FLO_type arg_a, FLO_type arg_b) 132390075Sobrien{ 132490075Sobrien fp_number_type a; 132590075Sobrien fp_number_type b; 132690075Sobrien FLO_union_type au, bu; 132790075Sobrien 132890075Sobrien au.value = arg_a; 132990075Sobrien bu.value = arg_b; 133090075Sobrien 133190075Sobrien unpack_d (&au, &a); 133290075Sobrien unpack_d (&bu, &b); 133390075Sobrien 133490075Sobrien return (isnan (&a) || isnan (&b)); 133590075Sobrien} 133690075Sobrien#endif /* L_unord_sf || L_unord_df */ 133790075Sobrien 1338117395Skan#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) 133918334SpeterFLO_type 134018334Spetersi_to_float (SItype arg_a) 134118334Speter{ 134218334Speter fp_number_type in; 134318334Speter 134418334Speter in.class = CLASS_NUMBER; 134518334Speter in.sign = arg_a < 0; 134618334Speter if (!arg_a) 134718334Speter { 134818334Speter in.class = CLASS_ZERO; 134918334Speter } 135018334Speter else 135118334Speter { 1352169689Skan USItype uarg; 1353169689Skan int shift; 135418334Speter in.normal_exp = FRACBITS + NGARDS; 135518334Speter if (in.sign) 135618334Speter { 135718334Speter /* Special case for minint, since there is no +ve integer 135818334Speter representation for it */ 135990075Sobrien if (arg_a == (- MAX_SI_INT - 1)) 136018334Speter { 136190075Sobrien return (FLO_type)(- MAX_SI_INT - 1); 136218334Speter } 1363169689Skan uarg = (-arg_a); 136418334Speter } 136518334Speter else 1366169689Skan uarg = arg_a; 136718334Speter 1368169689Skan in.fraction.ll = uarg; 1369169689Skan shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS); 1370169689Skan if (shift > 0) 137118334Speter { 1372169689Skan in.fraction.ll <<= shift; 1373169689Skan in.normal_exp -= shift; 137418334Speter } 137518334Speter } 137618334Speter return pack_d (&in); 137718334Speter} 137890075Sobrien#endif /* L_si_to_sf || L_si_to_df */ 137990075Sobrien 1380117395Skan#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) 138190075SobrienFLO_type 138290075Sobrienusi_to_float (USItype arg_a) 138390075Sobrien{ 138490075Sobrien fp_number_type in; 138590075Sobrien 138690075Sobrien in.sign = 0; 138790075Sobrien if (!arg_a) 138890075Sobrien { 138990075Sobrien in.class = CLASS_ZERO; 139090075Sobrien } 139190075Sobrien else 139290075Sobrien { 1393169689Skan int shift; 139490075Sobrien in.class = CLASS_NUMBER; 139590075Sobrien in.normal_exp = FRACBITS + NGARDS; 139690075Sobrien in.fraction.ll = arg_a; 139790075Sobrien 1398169689Skan shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS); 1399169689Skan if (shift < 0) 140090075Sobrien { 1401169689Skan fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1); 1402169689Skan in.fraction.ll >>= -shift; 1403169689Skan in.fraction.ll |= (guard != 0); 1404169689Skan in.normal_exp -= shift; 140590075Sobrien } 1406169689Skan else if (shift > 0) 1407169689Skan { 1408169689Skan in.fraction.ll <<= shift; 1409169689Skan in.normal_exp -= shift; 1410169689Skan } 141190075Sobrien } 141290075Sobrien return pack_d (&in); 141390075Sobrien} 141450397Sobrien#endif 141518334Speter 1416117395Skan#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) 141718334SpeterSItype 141818334Speterfloat_to_si (FLO_type arg_a) 141918334Speter{ 142018334Speter fp_number_type a; 142118334Speter SItype tmp; 142290075Sobrien FLO_union_type au; 142318334Speter 142490075Sobrien au.value = arg_a; 142590075Sobrien unpack_d (&au, &a); 142690075Sobrien 142718334Speter if (iszero (&a)) 142818334Speter return 0; 142918334Speter if (isnan (&a)) 143018334Speter return 0; 1431117395Skan /* get reasonable MAX_SI_INT... */ 143218334Speter if (isinf (&a)) 143350397Sobrien return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT; 143418334Speter /* it is a number, but a small one */ 143518334Speter if (a.normal_exp < 0) 143618334Speter return 0; 143790075Sobrien if (a.normal_exp > BITS_PER_SI - 2) 143818334Speter return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT; 143918334Speter tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp); 144018334Speter return a.sign ? (-tmp) : (tmp); 144118334Speter} 144290075Sobrien#endif /* L_sf_to_si || L_df_to_si */ 144318334Speter 1444117395Skan#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) 1445117395Skan#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) 144618334Speter/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, 144718334Speter we also define them for GOFAST because the ones in libgcc2.c have the 144818334Speter wrong names and I'd rather define these here and keep GOFAST CYG-LOC's 144918334Speter out of libgcc2.c. We can't define these here if not GOFAST because then 145018334Speter there'd be duplicate copies. */ 145118334Speter 145218334SpeterUSItype 145318334Speterfloat_to_usi (FLO_type arg_a) 145418334Speter{ 145518334Speter fp_number_type a; 145690075Sobrien FLO_union_type au; 145718334Speter 145890075Sobrien au.value = arg_a; 145990075Sobrien unpack_d (&au, &a); 146090075Sobrien 146118334Speter if (iszero (&a)) 146218334Speter return 0; 146318334Speter if (isnan (&a)) 146418334Speter return 0; 146518334Speter /* it is a negative number */ 146618334Speter if (a.sign) 146718334Speter return 0; 1468117395Skan /* get reasonable MAX_USI_INT... */ 146950397Sobrien if (isinf (&a)) 147050397Sobrien return MAX_USI_INT; 147118334Speter /* it is a number, but a small one */ 147218334Speter if (a.normal_exp < 0) 147318334Speter return 0; 147490075Sobrien if (a.normal_exp > BITS_PER_SI - 1) 147518334Speter return MAX_USI_INT; 147618334Speter else if (a.normal_exp > (FRACBITS + NGARDS)) 147750397Sobrien return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS)); 147818334Speter else 147918334Speter return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp); 148018334Speter} 148190075Sobrien#endif /* US_SOFTWARE_GOFAST */ 148290075Sobrien#endif /* L_sf_to_usi || L_df_to_usi */ 148318334Speter 1484117395Skan#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) 148518334SpeterFLO_type 148618334Speternegate (FLO_type arg_a) 148718334Speter{ 148818334Speter fp_number_type a; 148990075Sobrien FLO_union_type au; 149018334Speter 149190075Sobrien au.value = arg_a; 149290075Sobrien unpack_d (&au, &a); 149390075Sobrien 149418334Speter flip_sign (&a); 149518334Speter return pack_d (&a); 149618334Speter} 149790075Sobrien#endif /* L_negate_sf || L_negate_df */ 149818334Speter 149918334Speter#ifdef FLOAT 150018334Speter 150150397Sobrien#if defined(L_make_sf) 150218334SpeterSFtype 150318334Speter__make_fp(fp_class_type class, 150418334Speter unsigned int sign, 150518334Speter int exp, 150618334Speter USItype frac) 150718334Speter{ 150818334Speter fp_number_type in; 150918334Speter 151018334Speter in.class = class; 151118334Speter in.sign = sign; 151218334Speter in.normal_exp = exp; 151318334Speter in.fraction.ll = frac; 151418334Speter return pack_d (&in); 151518334Speter} 151690075Sobrien#endif /* L_make_sf */ 151718334Speter 151818334Speter#ifndef FLOAT_ONLY 151918334Speter 152018334Speter/* This enables one to build an fp library that supports float but not double. 152118334Speter Otherwise, we would get an undefined reference to __make_dp. 152218334Speter This is needed for some 8-bit ports that can't handle well values that 152318334Speter are 8-bytes in size, so we just don't support double for them at all. */ 152418334Speter 152550397Sobrien#if defined(L_sf_to_df) 152618334SpeterDFtype 152718334Spetersf_to_df (SFtype arg_a) 152818334Speter{ 152918334Speter fp_number_type in; 153090075Sobrien FLO_union_type au; 153118334Speter 153290075Sobrien au.value = arg_a; 153390075Sobrien unpack_d (&au, &in); 153490075Sobrien 153518334Speter return __make_dp (in.class, in.sign, in.normal_exp, 153618334Speter ((UDItype) in.fraction.ll) << F_D_BITOFF); 153718334Speter} 153890075Sobrien#endif /* L_sf_to_df */ 153918334Speter 1540117395Skan#if defined(L_sf_to_tf) && defined(TMODES) 1541117395SkanTFtype 1542117395Skansf_to_tf (SFtype arg_a) 1543117395Skan{ 1544117395Skan fp_number_type in; 1545117395Skan FLO_union_type au; 1546117395Skan 1547117395Skan au.value = arg_a; 1548117395Skan unpack_d (&au, &in); 1549117395Skan 1550117395Skan return __make_tp (in.class, in.sign, in.normal_exp, 1551117395Skan ((UTItype) in.fraction.ll) << F_T_BITOFF); 1552117395Skan} 1553117395Skan#endif /* L_sf_to_df */ 1554117395Skan 155590075Sobrien#endif /* ! FLOAT_ONLY */ 155690075Sobrien#endif /* FLOAT */ 155718334Speter 155818334Speter#ifndef FLOAT 155918334Speter 156018334Speterextern SFtype __make_fp (fp_class_type, unsigned int, int, USItype); 156118334Speter 156250397Sobrien#if defined(L_make_df) 156318334SpeterDFtype 156418334Speter__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac) 156518334Speter{ 156618334Speter fp_number_type in; 156718334Speter 156818334Speter in.class = class; 156918334Speter in.sign = sign; 157018334Speter in.normal_exp = exp; 157118334Speter in.fraction.ll = frac; 157218334Speter return pack_d (&in); 157318334Speter} 157490075Sobrien#endif /* L_make_df */ 157518334Speter 157650397Sobrien#if defined(L_df_to_sf) 157718334SpeterSFtype 157818334Speterdf_to_sf (DFtype arg_a) 157918334Speter{ 158018334Speter fp_number_type in; 158150397Sobrien USItype sffrac; 158290075Sobrien FLO_union_type au; 158318334Speter 158490075Sobrien au.value = arg_a; 158590075Sobrien unpack_d (&au, &in); 158650397Sobrien 158750397Sobrien sffrac = in.fraction.ll >> F_D_BITOFF; 158850397Sobrien 158950397Sobrien /* We set the lowest guard bit in SFFRAC if we discarded any non 159050397Sobrien zero bits. */ 159150397Sobrien if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0) 159250397Sobrien sffrac |= 1; 159350397Sobrien 159450397Sobrien return __make_fp (in.class, in.sign, in.normal_exp, sffrac); 159518334Speter} 159690075Sobrien#endif /* L_df_to_sf */ 159718334Speter 1598117395Skan#if defined(L_df_to_tf) && defined(TMODES) \ 1599117395Skan && !defined(FLOAT) && !defined(TFLOAT) 1600117395SkanTFtype 1601117395Skandf_to_tf (DFtype arg_a) 1602117395Skan{ 1603117395Skan fp_number_type in; 1604117395Skan FLO_union_type au; 1605117395Skan 1606117395Skan au.value = arg_a; 1607117395Skan unpack_d (&au, &in); 1608117395Skan 1609117395Skan return __make_tp (in.class, in.sign, in.normal_exp, 1610117395Skan ((UTItype) in.fraction.ll) << D_T_BITOFF); 1611117395Skan} 1612117395Skan#endif /* L_sf_to_df */ 1613117395Skan 1614117395Skan#ifdef TFLOAT 1615117395Skan#if defined(L_make_tf) 1616117395SkanTFtype 1617117395Skan__make_tp(fp_class_type class, 1618117395Skan unsigned int sign, 1619117395Skan int exp, 1620117395Skan UTItype frac) 1621117395Skan{ 1622117395Skan fp_number_type in; 1623117395Skan 1624117395Skan in.class = class; 1625117395Skan in.sign = sign; 1626117395Skan in.normal_exp = exp; 1627117395Skan in.fraction.ll = frac; 1628117395Skan return pack_d (&in); 1629117395Skan} 1630117395Skan#endif /* L_make_tf */ 1631117395Skan 1632117395Skan#if defined(L_tf_to_df) 1633117395SkanDFtype 1634117395Skantf_to_df (TFtype arg_a) 1635117395Skan{ 1636117395Skan fp_number_type in; 1637117395Skan UDItype sffrac; 1638117395Skan FLO_union_type au; 1639117395Skan 1640117395Skan au.value = arg_a; 1641117395Skan unpack_d (&au, &in); 1642117395Skan 1643117395Skan sffrac = in.fraction.ll >> D_T_BITOFF; 1644117395Skan 1645117395Skan /* We set the lowest guard bit in SFFRAC if we discarded any non 1646117395Skan zero bits. */ 1647117395Skan if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0) 1648117395Skan sffrac |= 1; 1649117395Skan 1650117395Skan return __make_dp (in.class, in.sign, in.normal_exp, sffrac); 1651117395Skan} 1652117395Skan#endif /* L_tf_to_df */ 1653117395Skan 1654117395Skan#if defined(L_tf_to_sf) 1655117395SkanSFtype 1656117395Skantf_to_sf (TFtype arg_a) 1657117395Skan{ 1658117395Skan fp_number_type in; 1659117395Skan USItype sffrac; 1660117395Skan FLO_union_type au; 1661117395Skan 1662117395Skan au.value = arg_a; 1663117395Skan unpack_d (&au, &in); 1664117395Skan 1665117395Skan sffrac = in.fraction.ll >> F_T_BITOFF; 1666117395Skan 1667117395Skan /* We set the lowest guard bit in SFFRAC if we discarded any non 1668117395Skan zero bits. */ 1669117395Skan if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0) 1670117395Skan sffrac |= 1; 1671117395Skan 1672117395Skan return __make_fp (in.class, in.sign, in.normal_exp, sffrac); 1673117395Skan} 1674117395Skan#endif /* L_tf_to_sf */ 1675117395Skan#endif /* TFLOAT */ 1676117395Skan 167790075Sobrien#endif /* ! FLOAT */ 167850397Sobrien#endif /* !EXTENDED_FLOAT_STUBS */ 1679