diff options
Diffstat (limited to 'libm/powerpc/s_modf.c')
-rw-r--r-- | libm/powerpc/s_modf.c | 138 |
1 files changed, 69 insertions, 69 deletions
diff --git a/libm/powerpc/s_modf.c b/libm/powerpc/s_modf.c index 66c0655f5..403c54b79 100644 --- a/libm/powerpc/s_modf.c +++ b/libm/powerpc/s_modf.c @@ -1,18 +1,18 @@ /******************************************************************************* ** File: rndint.c -** +** ** Contains: C source code for implementations of floating-point ** functions which round to integral value or format, as ** defined in header <fp.h>. In particular, this file ** contains implementations of functions rint, nearbyint, ** rinttol, round, roundtol, trunc, modf and modfl. This file ** targets PowerPC or Power platforms. -** +** ** Written by: A. Sazegari, Apple AltiVec Group ** Created originally by Jon Okada, Apple Numerics Group -** +** ** Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved -** +** ** Change History (most recent first): ** ** 13 Jul 01 ram replaced --setflm calls with inline assembly @@ -21,7 +21,7 @@ ** 1. removed double_t, put in double for now. ** 2. removed iclass from nearbyint. ** 3. removed wrong comments intrunc. -** 4. +** 4. ** 13 May 97 ali made performance improvements in rint, rinttol, roundtol ** and trunc by folding some of the taligent ideas into this ** implementation. nearbyint is faster than the one in taligent, @@ -33,7 +33,7 @@ ** 18 Feb 93 ali Changed the return value of fenv functions ** feclearexcept and feraiseexcept to their new ** NCEG X3J11.1/93-001 definitions. -** 16 Dec 92 JPO Removed __itrunc implementation to a +** 16 Dec 92 JPO Removed __itrunc implementation to a ** separate file. ** 15 Dec 92 JPO Added __itrunc implementation and modified ** rinttol to include conversion from double @@ -41,7 +41,7 @@ ** call __itrunc. ** 10 Dec 92 JPO Added modf (double) implementation. ** 04 Dec 92 JPO First created. -** +** *******************************************************************************/ #include <limits.h> @@ -81,14 +81,14 @@ static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }}; * This function calls fabs and copysign. * * * *******************************************************************************/ - + double nearbyint ( double x ) { double y; double OldEnvironment; - + y = twoTo52; - + asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ if ( fabs ( x ) >= y ) /* huge case is exact */ @@ -99,9 +99,9 @@ double nearbyint ( double x ) y = copysign ( y, x ); // restore old flags asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); - return ( y ); + return ( y ); } - + /******************************************************************************* * * * The function rinttol converts its double argument to integral value * @@ -120,38 +120,38 @@ long int rinttol ( double x ) DblInHex argument, OldEnvironment; unsigned long int xHead; register long int target; - + argument.dbl = x; target = ( argument.words.hi < signMask ); // flag positive sign xHead = argument.words.hi & 0x7ffffffful; // high 32 bits of x - - if ( target ) + + if ( target ) /******************************************************************************* * Sign of x is positive. * *******************************************************************************/ { - if ( xHead < 0x41dffffful ) + if ( xHead < 0x41dffffful ) { // x is safely in long range y = ( x + twoTo52 ) - twoTo52; // round at binary point argument.dbl = y + doubleToLong; // force result into argument.words.lo return ( ( long ) argument.words.lo ); } - + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment - - if ( xHead > 0x41dffffful ) + + if ( xHead > 0x41dffffful ) { // x is safely out of long range OldEnvironment.words.lo |= SET_INVALID; asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MAX ); } - + /******************************************************************************* * x > 0.0 and may or may not be out of range of long. * *******************************************************************************/ y = ( x + twoTo52 ) - twoTo52; // do rounding - if ( y > ( double ) LONG_MAX ) + if ( y > ( double ) LONG_MAX ) { // out of range of long OldEnvironment.words.lo |= SET_INVALID; asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); @@ -160,32 +160,32 @@ long int rinttol ( double x ) argument.dbl = y + doubleToLong; // in range return ( ( long ) argument.words.lo ); // return result & flags } - + /******************************************************************************* * Sign of x is negative. * *******************************************************************************/ - if ( xHead < 0x41e00000ul ) + if ( xHead < 0x41e00000ul ) { // x is safely in long range y = ( x - twoTo52 ) + twoTo52; argument.dbl = y + doubleToLong; return ( ( long ) argument.words.lo ); } - + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment - - if ( xHead > 0x41e00000ul ) + + if ( xHead > 0x41e00000ul ) { // x is safely out of long range OldEnvironment.words.lo |= SET_INVALID; asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( LONG_MIN ); } - + /******************************************************************************* * x < 0.0 and may or may not be out of range of long. * *******************************************************************************/ y = ( x - twoTo52 ) + twoTo52; // do rounding - if ( y < ( double ) LONG_MIN ) + if ( y < ( double ) LONG_MIN ) { // out of range of long OldEnvironment.words.lo |= SET_INVALID; asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); @@ -204,30 +204,30 @@ long int rinttol ( double x ) * return value is not equal to the operand. * * * *******************************************************************************/ - + double round ( double x ) - { + { DblInHex argument, OldEnvironment; register double y, z; register unsigned long int xHead; register long int target; - + argument.dbl = x; xHead = argument.words.hi & 0x7fffffffUL; // xHead <- high half of |x| target = ( argument.words.hi < signMask ); // flag positive sign - - if ( xHead < 0x43300000ul ) + + if ( xHead < 0x43300000ul ) /******************************************************************************* * Is |x| < 2.0^52? * *******************************************************************************/ { - if ( xHead < 0x3ff00000ul ) + if ( xHead < 0x3ff00000ul ) /******************************************************************************* * Is |x| < 1.0? * *******************************************************************************/ { asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment - if ( xHead < 0x3fe00000ul ) + if ( xHead < 0x3fe00000ul ) /******************************************************************************* * Is |x| < 0.5? * *******************************************************************************/ @@ -235,7 +235,7 @@ double round ( double x ) if ( ( xHead | argument.words.lo ) != 0ul ) OldEnvironment.words.lo |= 0x02000000ul; asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); - if ( target ) + if ( target ) return ( 0.0 ); else return ( -0.0 ); @@ -253,7 +253,7 @@ double round ( double x ) /******************************************************************************* * Is 1.0 < |x| < 2.0^52? * *******************************************************************************/ - if ( target ) + if ( target ) { // positive x y = ( x + twoTo52 ) - twoTo52; // round at binary point if ( y == x ) // exact case @@ -265,11 +265,11 @@ double round ( double x ) else return ( y ); } - + /******************************************************************************* * Is x < 0? * *******************************************************************************/ - else + else { y = ( x - twoTo52 ) + twoTo52; // round at binary point if ( y == x ) @@ -302,19 +302,19 @@ double round ( double x ) *******************************************************************************/ long int roundtol ( double x ) - { + { register double y, z; DblInHex argument, OldEnvironment; register unsigned long int xhi; register long int target; const DblInHex kTZ = {{ 0x0, 0x1 }}; const DblInHex kUP = {{ 0x0, 0x2 }}; - + argument.dbl = x; xhi = argument.words.hi & 0x7ffffffful; // high 32 bits of x target = ( argument.words.hi < signMask ); // flag positive sign - - if ( xhi > 0x41e00000ul ) + + if ( xhi > 0x41e00000ul ) /******************************************************************************* * Is x is out of long range or NaN? * *******************************************************************************/ @@ -327,19 +327,19 @@ long int roundtol ( double x ) else return ( LONG_MIN ); } - - if ( target ) + + if ( target ) /******************************************************************************* * Is sign of x is "+"? * *******************************************************************************/ { - if ( x < 2147483647.5 ) + if ( x < 2147483647.5 ) /******************************************************************************* * x is in the range of a long. * *******************************************************************************/ { y = ( x + doubleToLong ) - doubleToLong; // round at binary point - if ( y != x ) + if ( y != x ) { // inexact case asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kTZ.dbl )); // truncate rounding @@ -348,7 +348,7 @@ long int roundtol ( double x ) asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( ( long ) argument.words.lo ); } - + argument.dbl = y + doubleToLong; // force result into argument.words.lo return ( ( long ) argument.words.lo ); // return long result } @@ -363,13 +363,13 @@ long int roundtol ( double x ) /******************************************************************************* * x < 0.0 and may or may not be out of the range of a long. * *******************************************************************************/ - if ( x > -2147483648.5 ) + if ( x > -2147483648.5 ) /******************************************************************************* * x is in the range of a long. * *******************************************************************************/ { y = ( x + doubleToLong ) - doubleToLong; // round at binary point - if ( y != x ) + if ( y != x ) { // inexact case asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kUP.dbl )); // round up @@ -378,7 +378,7 @@ long int roundtol ( double x ) asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); return ( ( long ) argument.words.lo ); } - + argument.dbl = y + doubleToLong; return ( ( long ) argument.words.lo ); // return long result } @@ -398,29 +398,29 @@ long int roundtol ( double x ) * inexact if an ordered return value is not equal to the operand. * * * *******************************************************************************/ - + double trunc ( double x ) - { + { DblInHex argument,OldEnvironment; register double y; register unsigned long int xhi; register long int target; - + argument.dbl = x; xhi = argument.words.hi & 0x7fffffffUL; // xhi <- high half of |x| target = ( argument.words.hi < signMask ); // flag positive sign - - if ( xhi < 0x43300000ul ) + + if ( xhi < 0x43300000ul ) /******************************************************************************* * Is |x| < 2.0^53? * *******************************************************************************/ { - if ( xhi < 0x3ff00000ul ) + if ( xhi < 0x3ff00000ul ) /******************************************************************************* * Is |x| < 1.0? * *******************************************************************************/ { - if ( ( xhi | argument.words.lo ) != 0ul ) + if ( ( xhi | argument.words.lo ) != 0ul ) { // raise deserved INEXACT asm ("mffs %0" : "=f" (OldEnvironment.dbl)); OldEnvironment.words.lo |= 0x02000000ul; @@ -434,7 +434,7 @@ double trunc ( double x ) /******************************************************************************* * Is 1.0 < |x| < 2.0^52? * *******************************************************************************/ - if ( target ) + if ( target ) { y = ( x + twoTo52 ) - twoTo52; // round at binary point if ( y > x ) @@ -442,8 +442,8 @@ double trunc ( double x ) else return ( y ); } - - else + + else { y = ( x - twoTo52 ) + twoTo52; // round at binary point. if ( y < x ) @@ -470,7 +470,7 @@ double trunc ( double x ) *******************************************************************************/ /******************************************************************************* -* modf is the double implementation. * +* modf is the double implementation. * *******************************************************************************/ double modf ( double x, double *iptr ) @@ -478,19 +478,19 @@ double modf ( double x, double *iptr ) register double OldEnvironment, xtrunc; register unsigned long int xHead, signBit; DblInHex argument; - + argument.dbl = x; xHead = argument.words.hi & 0x7ffffffful; // |x| high bit pattern signBit = ( argument.words.hi & 0x80000000ul ); // isolate sign bit if (xHead == 0x7ff81fe0) signBit = signBit | 0; - - if ( xHead < 0x43300000ul ) + + if ( xHead < 0x43300000ul ) /******************************************************************************* * Is |x| < 2.0^53? * *******************************************************************************/ { - if ( xHead < 0x3ff00000ul ) + if ( xHead < 0x3ff00000ul ) /******************************************************************************* * Is |x| < 1.0? * *******************************************************************************/ @@ -515,18 +515,18 @@ double modf ( double x, double *iptr ) *iptr = xtrunc; // store integral part if ( x != xtrunc ) // nonzero fraction return ( x - xtrunc ); - else + else { // zero with x's sign argument.words.hi = signBit; argument.words.lo = 0ul; return ( argument.dbl ); } } - + *iptr = x; // x is integral or NaN if ( x != x ) // NaN is returned return x; - else + else { // zero with x's sign argument.words.hi = signBit; argument.words.lo = 0ul; |