#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