Main Page | Alphabetical List | Class List | File List | Class Members | File Members

math_suppl.h

Go to the documentation of this file.
00001 /*==================================================================
00002 !! Routines needed for the apeNEXT C library math.h
00003 !!          which are not standard to the C library
00004 !!
00005 !! $Id: math_suppl.h,v 2.10 2005/11/11 10:22:09 morinl Exp $
00006 !! from : math_next.hzt,v 1.3 2001/11/02 09:28:41 simma Exp
00007 !!
00008 !! ZZ version : Roberto De Pietri: v. 0.4 26/08/2001
00009 !! C conversion : N. Paschedag : 15/02/2002
00010 !!
00011 !! Implemented functions:
00012 !!   ->  isqrt(x)    <- 1/sqrt(x)
00013 !!   ->  isqrt2(x) 
00014 !!   ->  sqrt2(x) 
00015 !!   ->  sin_1oct(x) <- sin(x), -pi/4<x<pi/4  
00016 !!   ->  cos_1oct(x) <- cos(x), -pi/4<x<pi/4  
00017 !!   ->  atan_k(x)   <- atan(x), -1<x<1 
00018 !!   ->  asin_k(x)   <- asin(x), -1/2<x<1/2 
00019 !! in addition:
00020 !!   functions to which the following macros expand to (EL 05/09/2003)
00021 !!   -> _signbit(x)
00022 !!   -> _isfinite(x)
00023 !!   -> _isinf(x)
00024 !!   -> _isnan(x)
00025 !! added (EL 17/10/2003)
00026 !!   -> _isgreater(x,y)
00027 !!   -> _isgreaterequal(x,y)
00028 !!   -> _isless(x,y)
00029 !!   -> _islessequal(x,y)
00030 !!   -> _islessgreater(x,y)
00031 !!==================================================================*/
00032 
00033 #ifndef _MATH_H_              
00034 #include <math.h>
00035 #else
00036 #ifndef __MATH_SUPPL_H__
00037 #define __MATH_SUPPL_H__
00038 
00039 #include <nlibc.h>
00040 
00041 /*==================================================================
00042 !!  Function inverted square root (Newton iterations)
00043 !!==================================================================*/
00044 
00045 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00046 extern math_inline double isqrt( double a );
00047 #else
00048 #if defined(_uses_isqrt_math_suppl_h) || !defined(__cflow_processed)
00049 math_inline double isqrt( double a ) {
00050     register double ris, tmp_a2;
00051     register double three_half, one_half;
00052     register double aR;
00053 
00054     _math_setdouble(0x3FE0000000000000,one_half);       // 0.5
00055     _math_setdouble(0x3FF8000000000000,three_half);     // 1.5
00056 
00057     aR = a;
00058     asm("\tlutinvsqrt.L %0 %1" : "=r" (ris) : "r" (aR));
00059     asm("\tlutcross.H %0 $ZERO" : "=r" (ris));
00060 
00061     tmp_a2 = aR * one_half;
00062     ris = ris*( three_half - tmp_a2 * ris * ris);
00063     ris = ris*( three_half - tmp_a2 * ris * ris);
00064     ris = ris*( three_half - tmp_a2 * ris * ris);
00065     ris = ris*( three_half - tmp_a2 * ris * ris);
00066     return ris;
00067 }
00068 #endif
00069 #endif // Has Main
00070 
00071 /*-----------------------------------------------------------------
00072 !!
00073 !! The invsqrt function compute 1/Sqrt(x) using a table based guess  
00074 !! y0 = lutisqrt(x) such that r = 1 - x y0^2 is |r|<2^(-6.72)
00075 !!
00076 !! 1/Sqrt[x] = y0 ( 1 + r Q(r) )
00077 !!  
00078 !!        (    1          )    1
00079 !! Q(r) = ( --------- - 1 ) x ---
00080 !!        ( Sqrt[1-r]     )    r
00081 !!
00082 !! Q(r) has been approximated by a Remez minimax polynomial:
00083 !!
00084 !! degree = 5
00085 !! [a,b]  = [-0.01104854345604,0.01104854345604]
00086 !! w(x)   = r Sqrt(1-r)
00087 !! N Iter = 10000 
00088 !! Max Error = 6.6*10^-17
00089 !!
00090 !!---------------------------------------------------------------*/
00091 
00092 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00093 extern math_inline double isqrt2( double x );
00094 #else
00095 #if defined(_uses_isqrt2_math_suppl_h) || !defined(__cflow_processed)
00096 math_inline double isqrt2( double x ) {
00097     register double xx,y0,q0,q1;
00098     register double r,r2,Q;
00099     register double t1,t2,t3;
00100     register double p0,p1,p2,p3,p4,p5;
00101 
00102     // -- Remez coefficients for 1/sqrt(x) --
00103     _math_setdouble( 0x3fe0000000000176, p0 );
00104     _math_setdouble( 0x3fd8000000000640, p1 );
00105     _math_setdouble( 0x3fd3fffffd11f1d0, p2 );
00106     _math_setdouble( 0x3fd17ffffbfd0ec7, p3 );
00107     _math_setdouble( 0x3fcf81774c2db32f, p4 );
00108     _math_setdouble( 0x3fcce1962db980e2, p5 );
00109     
00110     xx = x;
00111     
00112     asm("\tlutisqrt.L %0 %1" : "=r" (y0) : "r" (xx));
00113     asm("\tlutcross.H %0 $ZERO" : "=r" (y0));
00114     
00115     q0 = y0 * y0;
00116     r  = (1.0) - xx * q0;
00117     r2 = r * r;
00118     
00119     t1 = p5 * r + p4;
00120     t2 = p3 * r + p2;
00121     t3 = p1 * r + p0;
00122     
00123     t1 = t1 * r2 + t2;
00124     Q  = t1 * r2 + t3;
00125     q1 = r  * y0;
00126     Q  = q1 * Q + y0;
00127 
00128     return Q;
00129 }
00130 #endif
00131 #endif // Has Main
00132 
00133 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00134 extern math_inline double sqrt2( double x ) ;
00135 #else
00136 #if defined(_uses_sqrt2_math_suppl_h) || !defined(__cflow_processed)
00137 math_inline double sqrt2( double x ) { 
00138     register double xx,y0,q0,q1;
00139     register double r,r2,Q;
00140     register double t1,t2,t3;
00141     register double p0,p1,p2,p3,p4,p5;
00142 
00143     // -- Remez coefficients for 1/sqrt(x) --
00144     _math_setdouble( 0x3fe0000000000176, p0 );
00145     _math_setdouble( 0x3fd8000000000640, p1 );
00146     _math_setdouble( 0x3fd3fffffd11f1d0, p2 );
00147     _math_setdouble( 0x3fd17ffffbfd0ec7, p3 );
00148     _math_setdouble( 0x3fcf81774c2db32f, p4 );
00149     _math_setdouble( 0x3fcce1962db980e2, p5 );
00150     
00151     xx = x;
00152     y0 = xx;
00153 
00154     where ( xx ) {
00155         asm("\tlutisqrt.L %0 %1" : "=r" (y0) : "r" (xx));
00156         asm("\tlutcross.H %0 $ZERO" : "=r" (y0));
00157     }
00158 
00159     q0 = y0 * y0;
00160     r  = 1.0 - xx * q0;
00161     r2 = r * r;
00162     
00163     y0 = y0 * xx;
00164     q1 = r  * y0;
00165     
00166     t1 = p5 * r + p4;
00167     t2 = p3 * r + p2;
00168     t3 = p1 * r + p0;
00169     
00170     t1 = t1 * r2 + t2;
00171     Q  = t1 * r2 + t3;
00172     
00173     Q  = q1 * Q + y0;
00174 
00175     return Q;
00176 }
00177 #endif
00178 #endif // Has Main
00179 
00180 /*-----------------------------------------------------------------
00181 !!
00182 !! Kernel function for the computation of Sin[x]
00183 !!
00184 !! Sin[x] = x ( 1 + x^2 Q[x^2] )    ;   -pi/4 < x < pi/4
00185 !!
00186 !!---------------------------------------------------------------*/
00187 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00188 extern math_inline double sin_1oct( double xx );
00189 #else
00190 #if defined(_uses_sin_1oct_math_suppl_h) || !defined(__cflow_processed)
00191 math_inline double sin_1oct( double xx ) {
00192     register double x, x2s, x4s, Qs;
00193     register double t1s, t2s, t3s;
00194     register double Sp0, Sp1, Sp2, Sp3, Sp4, Sp5, Sp6;
00195 
00196     // -- Remez coefficients for kernel sin --
00197     _math_setdouble(  0x0 , Sp0 );
00198     _math_setdouble(  0xbfc5555555555555 , Sp1 );
00199     _math_setdouble(  0x3f81111111110eb8 , Sp2 );
00200     _math_setdouble(  0xbf2a01a019f1c947 , Sp3 );
00201     _math_setdouble(  0x3ec71de384036e7d , Sp4 );
00202     _math_setdouble(  0xbe5ae60a561eeab5 , Sp5 );
00203     _math_setdouble(  0x3de5e3c6b7eeb28d , Sp6 );
00204 
00205     x = xx;
00206     x2s  = x * x;
00207     x4s = x2s * x2s;
00208     
00209     t1s = Sp5 + x2s * Sp6;
00210     t2s = Sp3 + x2s * Sp4;
00211     t3s = Sp1 + x2s * Sp2;
00212     
00213     t1s = t2s + x4s * t1s;
00214     Qs  = t3s + x4s * t1s;
00215     
00216     Qs  = x2s * Qs;
00217     Qs  = x + Qs * x;
00218     
00219     return Qs;
00220     
00221 }
00222 #endif
00223 #endif // Has Main
00224 
00225 /*-----------------------------------------------------------------
00226 !!
00227 !!
00228 !! Kernel function for the computation of Cos[x]
00229 !!
00230 !! Cos[x] = ( 1 + x^2 (1/2 + x^2 Q[x^2] ) )  ;   -pi/4 < x < pi/4
00231 !!
00232 !!---------------------------------------------------------------*/
00233 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00234 extern math_inline double cos_1oct( double x );
00235 #else
00236 #if defined(_uses_cos_1oct_math_suppl_h) || !defined(__cflow_processed)
00237 math_inline double cos_1oct( double x )
00238 { 
00239 
00240     register double x2c, x4c, Qc;
00241     register double t1c, t2c, t3c;
00242     register double Cp0, Cp1, Cp2, Cp3, Cp4, Cp5, Cp6;
00243 
00244     // -- Remez coefficients for kernel cos --
00245     _math_setdouble(  0xbfe0000000000000 , Cp0 );
00246     _math_setdouble(  0x3fa5555555555555 , Cp1 );
00247     _math_setdouble(  0xbf56c16c16c16910 , Cp2 );
00248     _math_setdouble(  0x3efa01a019f556d1 , Cp3 );
00249     _math_setdouble(  0xbe927e4fa28f90c6 , Cp4 );
00250     _math_setdouble(  0x3e21eeb7c6903ba2 , Cp5 );
00251     _math_setdouble(  0xbda908b4ef9a7e2e , Cp6 );
00252 
00253     x2c  = x * x;
00254     x4c = x2c * x2c;
00255 
00256     t1c = Cp5 + x2c * Cp6;
00257     t2c = Cp3 + x2c * Cp4;
00258     t3c = Cp1 + x2c * Cp2;
00259 
00260     t1c = t2c + x4c * t1c;
00261     Qc  = t3c + x4c * t1c;
00262 
00263     Qc  = x2c * Qc + Cp0;
00264     Qc  = (1.0) + x2c * Qc;
00265 
00266     return Qc;
00267 
00268 }
00269 #endif
00270 #endif // Has Main
00271 
00272 /*===================================================================
00273 !! Kernel function for the computation Atan(x) for |x|<1
00274 !!
00275 !! Res = Atan(x) = x + x^3 P22(x^2) 
00276 !!
00277 !! Where P22(y) is a degree 22 minimax polinomial approximating
00278 !! 
00279 !!        Atan(Sqrt[y])-Sqrt[y]
00280 !! P[y] = ---------------------
00281 !!            Sqrt[y] y
00282 !!
00283 !! degree = 22 
00284 !! [a,b]  = [0,1.0]
00285 !! w(y)   = y^3 / (Atan[Sqrt[y]]). 
00286 !! N Iter = 20000 
00287 !! Max Error = 2.38*10^-20  
00288 !!
00289 !!=================================================================*/
00290 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00291 extern math_inline double atan_k( double xx );
00292 #else
00293 #if defined(_uses_atan_k_math_suppl_h) || !defined(__cflow_processed)
00294 math_inline double atan_k( double xx )
00295 {
00296     register double x, x2, x3, P;
00297     register double r2, r4, Pa, Pb, Pc, Pd;
00298     register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
00299     register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
00300     register double p20, p21, p22;
00301 
00302     // -- Remez coefficients for atan --
00303     _math_setdouble(  0xbfd5555555555555 , p0  );
00304     _math_setdouble(  0x3fc9999999999971 , p1  );
00305     _math_setdouble(  0xbfc2492492490f58 , p2  );
00306     _math_setdouble(  0x3fbc71c71c68e470 , p3  );
00307     _math_setdouble(  0xbfb745d173541a68 , p4  );
00308     _math_setdouble(  0x3fb3b13affee80cf , p5  );
00309     _math_setdouble(  0xbfb111100b7ee084 , p6  );
00310     _math_setdouble(  0x3fae1e0a5cf4626e , p7  );
00311     _math_setdouble(  0xbfaaf1f6218828be , p8  );
00312     _math_setdouble(  0x3fa85e4efb1caacf , p9  );
00313     _math_setdouble(  0xbfa634430a602ac3 , p10 );
00314     _math_setdouble(  0x3fa446067f9429b9 , p11 );
00315     _math_setdouble(  0xbfa25977aa870234 , p12 );
00316     _math_setdouble(  0x3fa0269900f0cc1e , p13 );
00317     _math_setdouble(  0xbf9ae16c1b259e80 , p14 );
00318     _math_setdouble(  0x3f946df0d7c219b5 , p15 );
00319     _math_setdouble(  0xbf8b503895880e16 , p16 );
00320     _math_setdouble(  0x3f7ee47c1bf074f6 , p17 );
00321     _math_setdouble(  0xbf6c59076eef60d7 , p18 );
00322     _math_setdouble(  0x3f54123312f3c886 , p19 );
00323     _math_setdouble(  0xbf346fc2146a8776 , p20 );
00324     _math_setdouble(  0x3f0a81635a5fa23b , p21 );
00325     _math_setdouble(  0xbed063c89c3fdaca , p22 );
00326     
00327     x  = xx;
00328     x2 = x * x;
00329     x3 = x * x2;
00330     r2 = x2 * x2;
00331     r4 = r2 * r2;
00332     
00333     Pa = p20;
00334     Pa = r4 * Pa + p16;
00335     Pa = r4 * Pa + p12;
00336     Pa = r4 * Pa + p8;
00337     Pa = r4 * Pa + p4;
00338     Pa = r4 * Pa + p0;
00339     
00340     Pb = p21;
00341     Pb = r4 * Pb + p17;
00342     Pb = r4 * Pb + p13;
00343     Pb = r4 * Pb + p9;
00344     Pb = r4 * Pb + p5;
00345     Pb = r4 * Pb + p1;
00346     
00347     Pc =  p22;
00348     Pc = r4 * Pc + p18;
00349     Pc = r4 * Pc + p14;
00350     Pc = r4 * Pc + p10;
00351     Pc = r4 * Pc + p6;
00352     Pc = r4 * Pc + p2;
00353     
00354     Pd = p19;
00355     Pd = r4 * Pd + p15;
00356     Pd = r4 * Pd + p11;
00357     Pd = r4 * Pd + p7;
00358     Pd = r4 * Pd + p3;
00359     
00360     P = Pa + x2 * Pb + r2 * (Pc + x2 * Pd);
00361     P = x + x3 *P;
00362 
00363     return P;
00364 }
00365 #endif // atan_k()
00366 #endif // Has Main
00367 
00368 /* -----------------------------------------------------------------
00369 !!
00370 !! Main part: Computation of Asin(x) where -0.5 < x < 0.5
00371 !! 
00372 !! Res = Asin(x) = x + x^3 P19(x^2) 
00373 !!
00374 !! Where P19(y) is a degree 19 minimax polynomial approximating
00375 !! 
00376 !!        Asin(Sqrt[y])-Sqrt[y]
00377 !! P[y] = ---------------------
00378 !!            Sqrt[y] y
00379 !!
00380 !! degree = 19
00381 !! [a,b]  = [0,0.5]
00382 !! w(y)   = 1/(Asin[y]). 
00383 !! N Iter = 20000 
00384 !! Max Error = 4.41*10^-19  
00385 !!
00386 !! ---------------------------------------------------------------*/
00387 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00388 extern math_inline double asin_k( double xx );
00389 #else
00390 #if defined(_uses_asin_k_math_suppl_h) || !defined(__cflow_processed)
00391 math_inline double asin_k( double xx ) {
00392     register double x, x2, x3, P;
00393     register double r2, r4, Pa, Pb, Pc, Pd;
00394     register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
00395     register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
00396 
00397     // -- Remez coefficients for asin --
00398     _math_setdouble(  0x3fc5555555555555 , p0  );
00399     _math_setdouble(  0x3fb3333333333ff8 , p1  );
00400     _math_setdouble(  0x3fa6db6db6c8299f , p2  );
00401     _math_setdouble(  0x3f9f1c71d2cb0419 , p3  );
00402     _math_setdouble(  0x3f96e8b839a6eb1f , p4  );
00403     _math_setdouble(  0x3f91c5217cd11e53 , p5  );
00404     _math_setdouble(  0x3f8c91ddc9cccb8b , p6  );
00405     _math_setdouble(  0x3f880fff7f9aa201 , p7  );
00406     _math_setdouble(  0x3f7ff0699c7911d9 , p8  );
00407     _math_setdouble(  0x3f97c8c548d85470 , p9  );
00408     _math_setdouble(  0xbfb43c911218c604 , p10 );
00409     _math_setdouble(  0x3fd968af9c41272b , p11 );
00410     _math_setdouble(  0xbff5ecfed8eb21be , p12 );
00411     _math_setdouble(  0x400e2c596eac2542 , p13 );
00412     _math_setdouble(  0xc01fb74a405ddd3f , p14 );
00413     _math_setdouble(  0x4029446d2f84e0c3 , p15 );
00414     _math_setdouble(  0xc02d7056e867daf6 , p16 );
00415     _math_setdouble(  0x4027cbd4a391e704 , p17 );
00416     _math_setdouble(  0xc017e8e8f8f0fb8c , p18 );
00417     _math_setdouble(  0x3ff6d9ee9188998b , p19 );
00418     
00419     x  = xx;
00420     x2 = x * x;
00421     x3 = x * x2;
00422     
00423     r2 = x2 * x2;
00424     r4 = r2 * r2;
00425     
00426     Pa = p16;
00427     Pa = r4 * Pa + p12;
00428     Pa = r4 * Pa + p8;
00429     Pa = r4 * Pa + p4;
00430     Pa = r4 * Pa + p0;
00431     
00432     Pb = p17;
00433     Pb = r4 * Pb + p13;
00434     Pb = r4 * Pb + p9;
00435     Pb = r4 * Pb + p5;
00436     Pb = r4 * Pb + p1;
00437     
00438     Pc = p18;
00439     Pc = r4 * Pc + p14;
00440     Pc = r4 * Pc + p10;
00441     Pc = r4 * Pc + p6;
00442     Pc = r4 * Pc + p2;
00443     
00444     Pd = p19;
00445     Pd = r4 * Pd + p15;
00446     Pd = r4 * Pd + p11;
00447     Pd = r4 * Pd + p7;
00448     Pd = r4 * Pd + p3;
00449     
00450     P = Pa + x2 * Pb + r2 * (Pc + x2 * Pd);
00451     
00452     P = x + x3 * P;
00453 
00454     return P;
00455 }
00456 #endif // asin_k()
00457 #endif // Has Main
00458 
00459 /* -----------------------------------------------------
00460 !!  signbit(x)  -> see Notes in math.h
00461 !!  
00462 !!  alternativ: ie = ileadone.L(xu.xint) & 63
00463 !! ---------------------------------------------------------------*/
00464 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00465 extern math_inline int _signbit(double x);
00466 #else
00467 #if defined(_uses__signbit_math_suppl_h) || !defined(__cflow_processed)
00468 math_inline int _signbit(double x)
00469 {
00470 
00471     register unsigned int _mask;
00472     register int _sh,ie;
00473     register union {
00474       double xr;
00475       unsigned int xint;
00476     } xu;
00477 
00478     _mask=0x8000000000000000ULL;
00479     _sh  =63;
00480 
00481     xu.xr = x;
00482     ie = (_mask&xu.xint)>>_sh;
00483 
00484     return ie;
00485 }
00486 #endif
00487 #endif // Has Main
00488 /* -----------------------------------------------------
00489 !!  isfinite(x)  -> see Notes in math.h
00490 !!  version 1  clk cnt 110  run cnt 90
00491 !!  version 2  clk cnt 115  run cnt 93
00492 !! ---------------------------------------------------------------*/
00493 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00494 extern math_inline int _isfinite(double x);
00495 #else
00496 #if defined(_uses__isfinite_math_suppl_h) || !defined(__cflow_processed)
00497 math_inline int _isfinite(double x) {
00498 
00499 #ifdef __cflow_processed
00500 # warning "_isfinite(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
00501 #endif
00502 
00503     register unsigned int _emask;
00504     register int _sh,ie,ij,_im;
00505     register union {
00506       double xr;
00507       unsigned int xint;
00508     } xu;
00509 
00510     _emask=0x7FF0000000000000ULL;
00511 //    _sh  =52;
00512 //    _im  =0x7ff;
00513 
00514     xu.xr = x;
00515 /* version 1 */
00516     ie = _emask != (_emask&xu.xint); 
00517 
00518 /*    ie = 0x7ff != ((_emask&xu.xint)>>_sh); */
00519 /*  bit shift not necessary
00520     ii = (_emask&xu.xint)>>_sh;
00521     ie = 0;
00522     where (ii != _im) {
00523           ie = 1;
00524     }
00525 */
00526 /* version 2 */
00527 /*
00528     ii = (_emask&xu.xint);
00529     ie = 0;
00530     where (ii != _emask) {
00531           ie = 1;
00532     }
00533 */
00534 
00535     return ie;
00536 }
00537 #endif
00538 #endif // Has Main
00539 /* -----------------------------------------------------
00540 !!  isinf(x)  -> see Notes in math.h
00541 !! ---------------------------------------------------------------*/
00542 
00543 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00544 extern math_inline int _isinf(double x);
00545 #else
00546 #if defined(_uses__isinf_math_suppl_h) || !defined(__cflow_processed)
00547 math_inline int _isinf(double x) {
00548 
00549 #ifdef __cflow_processed
00550 # warning "_isinf(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
00551 #endif
00552 
00553     register unsigned int _emask,_mmask;
00554     register int ie,ii,ij;
00555     register union {
00556       double xr;
00557       unsigned int xint;
00558     } xu;
00559 
00560     _emask=0x7FF0000000000000ULL;
00561     _mmask=0x000fffffffffffffULL;
00562 
00563     xu.xr = x;
00564     ii = (_emask&xu.xint);
00565     ij = (_mmask&xu.xint);
00566     ie = 0;
00567     where ( (ii == _emask) && (ij == 0) ) {
00568           ie = 1;
00569     }
00570 
00571     return ie;
00572 }
00573 #endif
00574 #endif // Has Main
00575 /* -----------------------------------------------------
00576 !!  isnan(x)  -> see Notes in math.h
00577 !! ---------------------------------------------------------------*/
00578 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00579 extern math_inline int _isnan(double x) ;
00580 #else
00581 #if defined(_uses__isnan_math_suppl_h) || !defined(__cflow_processed)
00582 math_inline int _isnan(double x) {
00583 
00584 #ifdef __cflow_processed
00585 # warning "_isnan(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
00586 #endif
00587 
00588     register unsigned int _emask,_mmask;
00589     register int ie,ii,ij;
00590     register union {
00591       double xr;
00592       unsigned int xint;
00593     } xu;
00594 
00595     _emask=0x7FF0000000000000ULL;
00596     _mmask=0x000fffffffffffffULL;
00597 
00598     xu.xr = x;
00599     ii = (_emask&xu.xint);
00600     ij = (_mmask&xu.xint);
00601     ie = 0;
00602     where ( (ii == _emask) && (ij != 0) ) {
00603           ie = 1;
00604     }
00605 
00606     return ie;
00607 }
00608 #endif
00609 #endif // Has Main
00610 
00611 /* -----------------------------------------------------
00612 !!  fpclassify(x)  -> see Notes in math.h
00613 !! ---------------------------------------------------------------*/
00614 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00615 extern math_inline int _fpclassify(double x);
00616 #else
00617 #if defined(_uses__fpclassify_math_suppl_h) || !defined(__cflow_processed)
00618 math_inline int _fpclassify(double x)
00619 {
00620 #ifdef __cflow_processed
00621 # warning "_fpclassify(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
00622 #endif
00623     register unsigned int _emask,_mmask;
00624     register int ie,ii,ij;
00625     register union {
00626       double xr;
00627       unsigned int xint;
00628     } xu;
00629 
00630 
00631     _emask=0x7FF0000000000000ULL;
00632     _mmask=0x000fffffffffffffULL;
00633 
00634     xu.xr = x;
00635     ii = (_emask&xu.xint);
00636     ij = (_mmask&xu.xint);
00637 
00638 /* isfinite = isnormal: => 1 !! */
00639     ie = _emask != ii;
00640 
00641 /* isinf: => FP_INFINITE */
00642     where ( (ii == _emask) && (ij == 0) ) {
00643           ie = FP_INFINITE;
00644     }
00645 
00646 /* isnan: => FP_NAN */
00647     where ( (ii == _emask) && (ij != 0) ) {
00648           ie = FP_NAN;
00649     }
00650 
00651 /* iszero: => FP_ZERO */
00652     where ( ii == 0 ) {
00653           ie = FP_ZERO;
00654     }
00655 
00656     return ie;
00657 }
00658 #endif
00659 #endif // Has Main
00660 
00661 /* -----------------------------------------------------
00662 !!  isgreater(x,y)  -> see Notes in math.h
00663 !! ---------------------------------------------------------------*/
00664 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00665 extern math_inline int _isgreater(double x, double y);
00666 #else
00667 #if defined(_uses__isgreater_math_suppl_h) || !defined(__cflow_processed)
00668 math_inline int _isgreater(double x, double y) {
00669 
00670    register unsigned int _smask,_nsmask;
00671    register int sx,sy,ax,ay;
00672    register int ie;
00673    register double xr,yr;
00674 
00675    _smask  = 0x8000000000000000ull;
00676    _nsmask = 0x7fffffffffffffffull;
00677 
00678    xr = x;
00679    yr = y;
00680 
00681 // sign of x
00682    asm("iand.L %0 %1 %2" : "=r" (sx) : "r" (_smask), "r" (xr) );
00683    asm("lutcross.H %0 %1" : "=r" (sx) : "r" (sx) );
00684 // sign of y
00685    asm("iand.L %0 %1 %2" : "=r" (sy) : "r" (_smask), "r" (yr) );
00686    asm("lutcross.H %0 %1" : "=r" (sy) : "r" (sy) );
00687 
00688 // abs value of x
00689    asm("iand.L %0 %1 %2" : "=r" (ax) : "r" (_nsmask), "r" (xr) );
00690    asm("lutcross.H %0 %1" : "=r" (ax) : "r" (ax) );
00691 // abs value of y
00692    asm("iand.L %0 %1 %2" : "=r" (ay) : "r" (_nsmask), "r" (yr) );
00693    asm("lutcross.H %0 %1" : "=r" (ay) : "r" (ay) );
00694 /* wenn ich den kram eh in asm programmieren muss, dann
00695    vielleicht auch bis zum bitteren ende, i.e. mit
00696    stack-manipulationsroutinen fuer die where cond.,
00697    der assembler der where cond. sieht naemlich nicht
00698    berauschend aus                                    */
00699 
00700    ie = 0;
00701    where (   ( (ax>ay) && (sx==0) ) \
00702            ||( (ax<ay) && (sy!=0) ) ) {
00703       ie = 1;
00704    }
00705 
00706    return ie;
00707 }
00708 #endif
00709 #endif // Has Main
00710 /* -----------------------------------------------------
00711 !!  isgreaterequal(x,y)  -> see Notes in math.h
00712 !! ---------------------------------------------------------------*/
00713 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00714 extern math_inline double _isgreaterequal(double x, double y);
00715 #else
00716 #if defined(_uses__isgreaterequal_math_suppl_h) || !defined(__cflow_processed)
00717 math_inline double _isgreaterequal(double x, double y) {
00718 
00719    register unsigned int _smask,_nsmask;
00720    register int sx,sy,ax,ay;
00721    register int ie;
00722    register double xr,yr;
00723 
00724    _smask  = 0x8000000000000000ull;
00725    _nsmask = 0x7fffffffffffffffull;
00726 
00727    xr = x;
00728    yr = y;
00729 
00730 // sign of x
00731    asm("iand.L %0 %1 %2" : "=r" (sx) : "r" (_smask), "r" (xr) );
00732    asm("lutcross.H %0 %1" : "=r" (sx) : "r" (sx) );
00733 // sign of y
00734    asm("iand.L %0 %1 %2" : "=r" (sy) : "r" (_smask), "r" (yr) );
00735    asm("lutcross.H %0 %1" : "=r" (sy) : "r" (sy) );
00736 
00737 // abs value of x
00738    asm("iand.L %0 %1 %2" : "=r" (ax) : "r" (_nsmask), "r" (xr) );
00739    asm("lutcross.H %0 %1" : "=r" (ax) : "r" (ax) );
00740 // abs value of y
00741    asm("iand.L %0 %1 %2" : "=r" (ay) : "r" (_nsmask), "r" (yr) );
00742    asm("lutcross.H %0 %1" : "=r" (ay) : "r" (ay) );
00743 /* wenn ich den kram eh in asm programmieren muss, dann
00744    vielleicht auch bis zum bitteren ende, i.e. mit
00745    stack-manipulationsroutinen fuer die where cond.,
00746    der assembler der where cond. sieht naemlich nicht
00747    berauschend aus                                    */
00748 
00749    ie = 0;
00750    where (   ( (ax>=ay) && (sx==0) ) \
00751            ||( (ax<=ay) && (sy!=0) ) ) {
00752       ie = 1;
00753    }
00754 
00755    return ie;
00756 }
00757 #endif
00758 #endif // Has Main
00759 /* -----------------------------------------------------
00760 !!  isless(x,y)  -> see Notes in math.h
00761 !! ---------------------------------------------------------------*/
00762 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00763 extern math_inline double _isless(double x, double y);
00764 #else
00765 #if defined(_uses__isless_math_suppl_h) || !defined(__cflow_processed)
00766 math_inline double _isless(double x, double y) {
00767 
00768    register unsigned int _smask,_nsmask;
00769    register int sx,sy,ax,ay;
00770    register int ie;
00771    register double xr,yr;
00772 
00773    _smask  = 0x8000000000000000ull;
00774    _nsmask = 0x7fffffffffffffffull;
00775 
00776    xr = x;
00777    yr = y;
00778 
00779 // sign of x
00780    asm("iand.L %0 %1 %2" : "=r" (sx) : "r" (_smask), "r" (xr) );
00781    asm("lutcross.H %0 %1" : "=r" (sx) : "r" (sx) );
00782 // sign of y
00783    asm("iand.L %0 %1 %2" : "=r" (sy) : "r" (_smask), "r" (yr) );
00784    asm("lutcross.H %0 %1" : "=r" (sy) : "r" (sy) );
00785 
00786 // abs value of x
00787    asm("iand.L %0 %1 %2" : "=r" (ax) : "r" (_nsmask), "r" (xr) );
00788    asm("lutcross.H %0 %1" : "=r" (ax) : "r" (ax) );
00789 // abs value of y
00790    asm("iand.L %0 %1 %2" : "=r" (ay) : "r" (_nsmask), "r" (yr) );
00791    asm("lutcross.H %0 %1" : "=r" (ay) : "r" (ay) );
00792 /* wenn ich den kram eh in asm programmieren muss, dann
00793    vielleicht auch bis zum bitteren ende, i.e. mit
00794    stack-manipulationsroutinen fuer die where cond.,
00795    der assembler der where cond. sieht naemlich nicht
00796    berauschend aus                                    */
00797 
00798    ie = 0;
00799    where (   ( (ax<ay) && (sy==0) ) \
00800            ||( (ax>ay) && (sx!=0) ) ) {
00801       ie = 1;
00802    }
00803 
00804    return ie;
00805 }
00806 #endif
00807 #endif // Has Main
00808 /* -----------------------------------------------------
00809 !!  islessequal(x,y)  -> see Notes in math.h
00810 !! ---------------------------------------------------------------*/
00811 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00812 extern math_inline double _islessequal(double x, double y);
00813 #else
00814 #if defined(_uses__islessequal_math_suppl_h) || !defined(__cflow_processed)
00815 math_inline double _islessequal(double x, double y) {
00816 
00817    register unsigned int _smask,_nsmask;
00818    register int sx,sy,ax,ay;
00819    register int ie;
00820    register double xr,yr;
00821 
00822    _smask  = 0x8000000000000000ull;
00823    _nsmask = 0x7fffffffffffffffull;
00824 
00825    xr = x;
00826    yr = y;
00827 
00828 // sign of x
00829    asm("iand.L %0 %1 %2" : "=r" (sx) : "r" (_smask), "r" (xr) );
00830    asm("lutcross.H %0 %1" : "=r" (sx) : "r" (sx) );
00831 // sign of y
00832    asm("iand.L %0 %1 %2" : "=r" (sy) : "r" (_smask), "r" (yr) );
00833    asm("lutcross.H %0 %1" : "=r" (sy) : "r" (sy) );
00834 
00835 // abs value of x
00836    asm("iand.L %0 %1 %2" : "=r" (ax) : "r" (_nsmask), "r" (xr) );
00837    asm("lutcross.H %0 %1" : "=r" (ax) : "r" (ax) );
00838 // abs value of y
00839    asm("iand.L %0 %1 %2" : "=r" (ay) : "r" (_nsmask), "r" (yr) );
00840    asm("lutcross.H %0 %1" : "=r" (ay) : "r" (ay) );
00841 /* wenn ich den kram eh in asm programmieren muss, dann
00842    vielleicht auch bis zum bitteren ende, i.e. mit
00843    stack-manipulationsroutinen fuer die where cond.,
00844    der assembler der where cond. sieht naemlich nicht
00845    berauschend aus                                    */
00846 
00847    ie = 0;
00848    where (   ( (ax<=ay) && (sy==0) ) \
00849            ||( (ax>=ay) && (sx!=0) ) ) {
00850       ie = 1;
00851    }
00852 
00853    return ie;
00854 }
00855 #endif
00856 #endif // Has Main
00857 /* -----------------------------------------------------
00858 !!  islessgreater(x,y)  -> see Notes in math.h
00859 !! ---------------------------------------------------------------*/
00860 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00861 extern math_inline double _islessgreater(double x, double y);
00862 #else
00863 #if defined(_uses__islessgreater_math_suppl_h) || !defined(__cflow_processed)
00864 math_inline double _islessgreater(double x, double y) {
00865 
00866    register unsigned int _smask,_nsmask;
00867    register int sx,sy,ax,ay;
00868    register int ie;
00869    register double xr,yr;
00870 
00871    _smask  = 0x8000000000000000ull;
00872    _nsmask = 0x7fffffffffffffffull;
00873 
00874    xr = x;
00875    yr = y;
00876 
00877 // sign of x
00878    asm("iand.L %0 %1 %2" : "=r" (sx) : "r" (_smask), "r" (xr) );
00879    asm("lutcross.H %0 %1" : "=r" (sx) : "r" (sx) );
00880 // sign of y
00881    asm("iand.L %0 %1 %2" : "=r" (sy) : "r" (_smask), "r" (yr) );
00882    asm("lutcross.H %0 %1" : "=r" (sy) : "r" (sy) );
00883 
00884 // abs value of x
00885    asm("iand.L %0 %1 %2" : "=r" (ax) : "r" (_nsmask), "r" (xr) );
00886    asm("lutcross.H %0 %1" : "=r" (ax) : "r" (ax) );
00887 // abs value of y
00888    asm("iand.L %0 %1 %2" : "=r" (ay) : "r" (_nsmask), "r" (yr) );
00889    asm("lutcross.H %0 %1" : "=r" (ay) : "r" (ay) );
00890 /* wenn ich den kram eh in asm programmieren muss, dann
00891    vielleicht auch bis zum bitteren ende, i.e. mit
00892    stack-manipulationsroutinen fuer die where cond.,
00893    der assembler der where cond. sieht naemlich nicht
00894    berauschend aus                                    */
00895 
00896    ie = 1;
00897    where ( (ax==ay) && (sx==sy) ) {
00898       ie = 0;
00899    }
00900 
00901    return ie;
00902 }
00903 #endif
00904 #endif // Has Main
00905 
00906 /* -----------------------------------------------------
00907 !!  isunordered(x,y)  -> see Notes in math.h
00908 !! ---------------------------------------------------------------*/
00909 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00910 extern math_inline double _isunordered(double x, double y);
00911 #else
00912 #if defined(_uses__isunordered_math_suppl_h) || !defined(__cflow_processed)
00913 math_inline double _isunordered(double x, double y) {
00914 
00915     register unsigned int _emask,_mmask;
00916     register int ie,ii,ij,ie1;
00917     register union {
00918       double xr;
00919       unsigned int xint;
00920     } xu;
00921 
00922     _emask=0x7FF0000000000000ULL;
00923     _mmask=0x000fffffffffffffULL;
00924 
00925     xu.xr = x;
00926     ii = (_emask&xu.xint);
00927     ij = (_mmask&xu.xint);
00928     ie1 = 0;
00929     where ( (ii == _emask) && (ij != 0) ) {
00930           ie1 = 1;
00931     }
00932     xu.xr = y;
00933     ii = (_emask&xu.xint);
00934     ij = (_mmask&xu.xint);
00935     ie = 0;
00936     where ( (ii == _emask) && (ij != 0) ) {
00937           ie = ie1;
00938     }
00939 
00940     return ie;
00941 }
00942 #endif
00943 #endif // Has Main
00944 
00945 #endif //  __MATH_SUPPL_H__
00946 #endif //  ifdef _MATH_H_

Generated on Fri Jul 14 10:51:31 2006 for nlibc by doxygen 1.3.5