1*37da2899SCharles.Forsyth #include <ieeefp.h> 2*37da2899SCharles.Forsyth #include "lib9.h" 3*37da2899SCharles.Forsyth #include "mathi.h" 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsyth void FPinit(void)6*37da2899SCharles.ForsythFPinit(void) 7*37da2899SCharles.Forsyth { 8*37da2899SCharles.Forsyth fpsetsticky(0); /* Clear pending exceptions */ 9*37da2899SCharles.Forsyth fpsetround(FP_RN); 10*37da2899SCharles.Forsyth fpsetmask(FP_X_INV|FP_X_DZ|FP_X_UFL|FP_X_OFL); 11*37da2899SCharles.Forsyth } 12*37da2899SCharles.Forsyth 13*37da2899SCharles.Forsyth ulong getFPstatus(void)14*37da2899SCharles.ForsythgetFPstatus(void) 15*37da2899SCharles.Forsyth { 16*37da2899SCharles.Forsyth ulong fsr = 0; 17*37da2899SCharles.Forsyth fp_except fsr9=fpgetsticky(); 18*37da2899SCharles.Forsyth if(fsr9&FP_X_IMP) fsr |= INEX; 19*37da2899SCharles.Forsyth if(fsr9&FP_X_OFL) fsr |= OVFL; 20*37da2899SCharles.Forsyth if(fsr9&FP_X_UFL) fsr |= UNFL; 21*37da2899SCharles.Forsyth if(fsr9&FP_X_DZ) fsr |= ZDIV; 22*37da2899SCharles.Forsyth if(fsr9&FP_X_INV) fsr |= INVAL; 23*37da2899SCharles.Forsyth return fsr; 24*37da2899SCharles.Forsyth } 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth ulong FPstatus(ulong fsr,ulong mask)27*37da2899SCharles.ForsythFPstatus(ulong fsr, ulong mask) 28*37da2899SCharles.Forsyth { 29*37da2899SCharles.Forsyth ulong fsr9 = 0; 30*37da2899SCharles.Forsyth ulong old = getFPstatus(); 31*37da2899SCharles.Forsyth fsr = (fsr&mask) | (old&~mask); 32*37da2899SCharles.Forsyth if(fsr&INEX) fsr9 |= FP_X_IMP; 33*37da2899SCharles.Forsyth if(fsr&OVFL) fsr9 |= FP_X_OFL; 34*37da2899SCharles.Forsyth if(fsr&UNFL) fsr9 |= FP_X_UFL; 35*37da2899SCharles.Forsyth if(fsr&ZDIV) fsr9 |= FP_X_DZ; 36*37da2899SCharles.Forsyth if(fsr&INVAL) fsr9 |= FP_X_INV; 37*37da2899SCharles.Forsyth /* fpsetmask(fsr9); */ 38*37da2899SCharles.Forsyth fpsetsticky(fsr9); 39*37da2899SCharles.Forsyth return(old&mask); 40*37da2899SCharles.Forsyth } 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsyth ulong getFPcontrol(void)43*37da2899SCharles.ForsythgetFPcontrol(void) 44*37da2899SCharles.Forsyth { 45*37da2899SCharles.Forsyth ulong fcr = 0; 46*37da2899SCharles.Forsyth fp_except fpc = fpgetmask(); 47*37da2899SCharles.Forsyth fp_rnd fpround = fpgetround(); 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth if(fpc&FP_X_INV) 50*37da2899SCharles.Forsyth fcr|=INVAL; 51*37da2899SCharles.Forsyth if(fpc&FP_X_DZ) 52*37da2899SCharles.Forsyth fcr|=ZDIV; 53*37da2899SCharles.Forsyth if(fpc&FP_X_OFL) 54*37da2899SCharles.Forsyth fcr|=OVFL; 55*37da2899SCharles.Forsyth if(fpc&FP_X_UFL) 56*37da2899SCharles.Forsyth fcr|=UNFL; 57*37da2899SCharles.Forsyth if(fpc&FP_X_IMP) 58*37da2899SCharles.Forsyth fcr|=INEX; 59*37da2899SCharles.Forsyth switch(fpround){ 60*37da2899SCharles.Forsyth case FP_RZ: 61*37da2899SCharles.Forsyth fcr|=RND_Z; 62*37da2899SCharles.Forsyth break; 63*37da2899SCharles.Forsyth case FP_RN: 64*37da2899SCharles.Forsyth fcr|=RND_NINF; 65*37da2899SCharles.Forsyth break; 66*37da2899SCharles.Forsyth case FP_RP: 67*37da2899SCharles.Forsyth fcr|=RND_PINF; 68*37da2899SCharles.Forsyth break; 69*37da2899SCharles.Forsyth case FP_RM: 70*37da2899SCharles.Forsyth fcr|=RND_NR; 71*37da2899SCharles.Forsyth } 72*37da2899SCharles.Forsyth return fcr; 73*37da2899SCharles.Forsyth } 74*37da2899SCharles.Forsyth ulong FPcontrol(ulong fcr,ulong mask)75*37da2899SCharles.ForsythFPcontrol(ulong fcr, ulong mask) 76*37da2899SCharles.Forsyth { 77*37da2899SCharles.Forsyth fp_except fc=0; 78*37da2899SCharles.Forsyth fp_rnd round; 79*37da2899SCharles.Forsyth ulong old = getFPcontrol(); 80*37da2899SCharles.Forsyth ulong changed = mask&(fcr^old); 81*37da2899SCharles.Forsyth fcr = (fcr&mask) | (old&~mask); 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsyth if(fcr&INEX) fc |= FP_X_IMP; 84*37da2899SCharles.Forsyth if(fcr&OVFL) fc |= FP_X_OFL; 85*37da2899SCharles.Forsyth if(fcr&UNFL) fc |= FP_X_UFL; 86*37da2899SCharles.Forsyth if(fcr&ZDIV) fc |= FP_X_DZ; 87*37da2899SCharles.Forsyth if(fcr&INVAL) fc |= FP_X_INV; 88*37da2899SCharles.Forsyth 89*37da2899SCharles.Forsyth switch(fcr&RND_MASK){ 90*37da2899SCharles.Forsyth case RND_NR: round |= FP_RM; break; 91*37da2899SCharles.Forsyth case RND_NINF: round |= FP_RN; break; 92*37da2899SCharles.Forsyth case RND_PINF: round |= FP_RP; break; 93*37da2899SCharles.Forsyth case RND_Z: round |= FP_RZ; break; 94*37da2899SCharles.Forsyth } 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth fpsetround(round); 97*37da2899SCharles.Forsyth fpsetmask(fc); 98*37da2899SCharles.Forsyth return(old&mask); 99*37da2899SCharles.Forsyth } 100