1 #include "lib9.h" 2 #include "fpuctl.h" 3 #include "mathi.h" 4 5 void 6 FPinit(void) 7 { 8 setfsr(0); /* Clear pending exceptions */ 9 setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPUNFL|FPOVFL); 10 } 11 12 ulong 13 getFPstatus(void) 14 { 15 ulong fsr = 0, fsr9 = getfsr(); 16 /* on specific machines, could be table lookup */ 17 if(fsr9&FPAINEX) fsr |= INEX; 18 if(fsr9&FPAOVFL) fsr |= OVFL; 19 if(fsr9&FPAUNFL) fsr |= UNFL; 20 if(fsr9&FPAZDIV) fsr |= ZDIV; 21 if(fsr9&FPAINVAL) fsr |= INVAL; 22 return fsr; 23 } 24 25 ulong 26 FPstatus(ulong fsr, ulong mask) 27 { 28 ulong fsr9 = 0; 29 ulong old = getFPstatus(); 30 fsr = (fsr&mask) | (old&~mask); 31 if(fsr&INEX) fsr9 |= FPAINEX; 32 if(fsr&OVFL) fsr9 |= FPAOVFL; 33 if(fsr&UNFL) fsr9 |= FPAUNFL; 34 if(fsr&ZDIV) fsr9 |= FPAZDIV; 35 if(fsr&INVAL) fsr9 |= FPAINVAL; 36 setfsr(fsr9); 37 return(old&mask); 38 } 39 40 ulong 41 getFPcontrol(void) 42 { 43 ulong fcr = 0, fcr9 = getfcr(); 44 switch(fcr9&FPRMASK){ 45 case FPRNR: fcr = RND_NR; break; 46 case FPRNINF: fcr = RND_NINF; break; 47 case FPRPINF: fcr = RND_PINF; break; 48 case FPRZ: fcr = RND_Z; break; 49 } 50 if(fcr9&FPINEX) fcr |= INEX; 51 if(fcr9&FPOVFL) fcr |= OVFL; 52 if(fcr9&FPUNFL) fcr |= UNFL; 53 if(fcr9&FPZDIV) fcr |= ZDIV; 54 if(fcr9&FPINVAL) fcr |= INVAL; 55 return fcr; 56 } 57 58 ulong 59 FPcontrol(ulong fcr, ulong mask) 60 { 61 ulong fcr9 = FPPDBL; 62 ulong old = getFPcontrol(); 63 fcr = (fcr&mask) | (old&~mask); 64 if(fcr&INEX) fcr9 |= FPINEX; 65 if(fcr&OVFL) fcr9 |= FPOVFL; 66 if(fcr&UNFL) fcr9 |= FPUNFL; 67 if(fcr&ZDIV) fcr9 |= FPZDIV; 68 if(fcr&INVAL) fcr9 |= FPINVAL; 69 switch(fcr&RND_MASK){ 70 case RND_NR: fcr9 |= FPRNR; break; 71 case RND_NINF: fcr9 |= FPRNINF; break; 72 case RND_PINF: fcr9 |= FPRPINF; break; 73 case RND_Z: fcr9 |= FPRZ; break; 74 } 75 setfcr(fcr9); 76 return(old&mask); 77 } 78 79