FPcontrol-Solaris.c 1.8 KB

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