home *** CD-ROM | disk | FTP | other *** search
- #ifndef _FPU_H
- #define _FPU_H
-
- /*
- * include file for FPU instructions.
- *
- * It would be nice to be able to communicate the various forms of these
- * insns to the compiler, but it is not to be.
- *
- * For instance, "fsinb #1,fp0" is reasonable and small, but
- * I don't want to have multiple #define's for 'sin(x)'.
- */
-
- /*
- * The _81 macro below turns "#define sin(x) _81("fsinx",x)" into this:
- *
- * #define sin(x) ({double in=(x), out;
- * asm("fsinx %1,%0" : "=f" (out) : "f" (in)); out;})
- *
- * And then a call like x=sin(x) (for global double x) produces this
- * assembly code:
- *
- * fmoved _x,fp0
- * fsinx fp0,fp0
- * fmoved fp0,_x
- */
-
- #define _81(insn,x) (double)({double in=(x), out; \
- __asm(insn " %1,%0" : "=f" (out) : "f" (in)); out;})
-
- #define acos(x) _81("facosx",x)
- #define asin(x) _81("fasinx",x)
- #define atan(x) _81("fatanx",x)
- #define atanh(x) _81("fatanhx",x)
- #define cos(x) _81("fcosx",x)
- #define cosh(x) _81("fcoshx",x)
- #define dabs(x) _81("fabsx",x)
- #define fabs(x) dabs(x)
- #define exp(x) _81("fetoxx",x)
- #define log(x) _81("flognx",x)
- #define log10(x) _81("flog10x",x)
- #define sin(x) _81("fsinx",x)
- #define sinh(x) _81("fsinhx",x)
- #define sqrt(x) _81("fsqrtx",x)
- #define tan(x) _81("ftanx",x)
- #define tanh(x) _81("ftanhx",x)
-
- #define floor(x) _81("fintrzx",x)
- #define ceil(x) (- _81("fintrzx",-(x)))
-
- #define rint(x) _81("fintx",x)
-
- #define fmod(x,y) (double)({double _x=(x), _y=(y); \
- __asm("fmodx %2,%0" : "=f" (_x) : "0" (_x), "f" (_y)); _x;})
-
- #define copysign(x,y) ({double _x=x, _y=y; (y>0.0 ? (x>0.0 ? x : -x) : (x<0.0 ? x : -x));})
-
- static inline double pow(double x,double y)
- {
- double temp;
- long l;
- if (x <= 0.) {
- if (x == 0.) {
- if (y <= 0.) goto domain;
- return 0.;
- }
- l = y;
- if (l != y) goto domain;
- temp = exp(y * log(-x));
- if (l & 1) temp = -temp;
- return temp;
- }
- return (exp(y * log(x)));
-
- domain:
- return HUGE;
- }
-
- #endif
-